package client
import (
"fmt"
"net"
"time"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
tpt "github.com/libp2p/go-libp2p/core/transport"
ma "github.com/multiformats/go-multiaddr"
manet "github.com/multiformats/go-multiaddr/net"
)
var HopTagWeight = 5
type statLimitDuration struct {}
type statLimitData struct {}
var (
StatLimitDuration = statLimitDuration {}
StatLimitData = statLimitData {}
)
type Conn struct {
stream network .Stream
remote peer .AddrInfo
stat network .ConnStats
client *Client
}
type NetAddr struct {
Relay string
Remote string
}
var _ net .Addr = (*NetAddr )(nil )
func (n *NetAddr ) Network () string {
return "libp2p-circuit-relay"
}
func (n *NetAddr ) String () string {
return fmt .Sprintf ("relay[%s-%s]" , n .Remote , n .Relay )
}
var _ manet .Conn = (*Conn )(nil )
func (c *Conn ) Close () error {
c .untagHop ()
return c .stream .Reset ()
}
func (c *Conn ) Read (buf []byte ) (int , error ) {
return c .stream .Read (buf )
}
func (c *Conn ) Write (buf []byte ) (int , error ) {
return c .stream .Write (buf )
}
func (c *Conn ) SetDeadline (t time .Time ) error {
return c .stream .SetDeadline (t )
}
func (c *Conn ) SetReadDeadline (t time .Time ) error {
return c .stream .SetReadDeadline (t )
}
func (c *Conn ) SetWriteDeadline (t time .Time ) error {
return c .stream .SetWriteDeadline (t )
}
func (c *Conn ) RemoteMultiaddr () ma .Multiaddr {
relayAddr , err := ma .NewComponent (
ma .ProtocolWithCode (ma .P_P2P ).Name ,
c .stream .Conn ().RemotePeer ().String (),
)
if err != nil {
log .Error (err )
return ma .Join (c .stream .Conn ().RemoteMultiaddr (), circuitAddr )
}
return ma .Join (c .stream .Conn ().RemoteMultiaddr (), relayAddr .Multiaddr (), circuitAddr )
}
func (c *Conn ) LocalMultiaddr () ma .Multiaddr {
return c .stream .Conn ().LocalMultiaddr ()
}
func (c *Conn ) LocalAddr () net .Addr {
na , err := manet .ToNetAddr (c .stream .Conn ().LocalMultiaddr ())
if err != nil {
log .Error ("failed to convert local multiaddr to net addr:" , err )
return nil
}
return na
}
func (c *Conn ) RemoteAddr () net .Addr {
return &NetAddr {
Relay : c .stream .Conn ().RemotePeer ().String (),
Remote : c .remote .ID .String (),
}
}
var _ network .ConnStat = (*Conn )(nil )
func (c *Conn ) Stat () network .ConnStats {
return c .stat
}
func (c *Conn ) tagHop () {
c .client .mx .Lock ()
defer c .client .mx .Unlock ()
p := c .stream .Conn ().RemotePeer ()
c .client .hopCount [p ]++
if c .client .hopCount [p ] == 1 {
c .client .host .ConnManager ().TagPeer (p , "relay-hop-stream" , HopTagWeight )
}
}
func (c *Conn ) untagHop () {
c .client .mx .Lock ()
defer c .client .mx .Unlock ()
p := c .stream .Conn ().RemotePeer ()
c .client .hopCount [p ]--
if c .client .hopCount [p ] == 0 {
c .client .host .ConnManager ().UntagPeer (p , "relay-hop-stream" )
delete (c .client .hopCount , p )
}
}
type capableConnWithStat interface {
tpt .CapableConn
network .ConnStat
}
type capableConn struct {
capableConnWithStat
}
var transportName = ma .ProtocolWithCode (ma .P_CIRCUIT ).Name
func (c capableConn ) ConnState () network .ConnectionState {
return network .ConnectionState {
Transport : transportName ,
}
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .