2018-07-04 10:51:47 +00:00
|
|
|
package relay
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net"
|
2019-06-09 07:24:20 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/libp2p/go-libp2p-core/host"
|
|
|
|
"github.com/libp2p/go-libp2p-core/network"
|
|
|
|
"github.com/libp2p/go-libp2p-core/peer"
|
2018-07-04 10:51:47 +00:00
|
|
|
|
|
|
|
ma "github.com/multiformats/go-multiaddr"
|
|
|
|
manet "github.com/multiformats/go-multiaddr-net"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Conn struct {
|
2019-06-09 07:24:20 +00:00
|
|
|
stream network.Stream
|
|
|
|
remote peer.AddrInfo
|
|
|
|
host host.Host
|
2018-07-04 10:51:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type NetAddr struct {
|
|
|
|
Relay string
|
|
|
|
Remote string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (n *NetAddr) Network() string {
|
|
|
|
return "libp2p-circuit-relay"
|
|
|
|
}
|
|
|
|
|
|
|
|
func (n *NetAddr) String() string {
|
|
|
|
return fmt.Sprintf("relay[%s-%s]", n.Remote, n.Relay)
|
|
|
|
}
|
|
|
|
|
2019-06-09 07:24:20 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2018-07-04 10:51:47 +00:00
|
|
|
func (c *Conn) RemoteAddr() net.Addr {
|
|
|
|
return &NetAddr{
|
2019-06-09 07:24:20 +00:00
|
|
|
Relay: c.stream.Conn().RemotePeer().Pretty(),
|
2018-07-04 10:51:47 +00:00
|
|
|
Remote: c.remote.ID.Pretty(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-09 07:24:20 +00:00
|
|
|
// Increment the underlying relay connection tag by 1, thus increasing its protection from
|
|
|
|
// connection pruning. This ensures that connections to relays are not accidentally closed,
|
|
|
|
// by the connection manager, taking with them all the relayed connections (that may themselves
|
|
|
|
// be protected).
|
|
|
|
func (c *Conn) tagHop() {
|
|
|
|
c.host.ConnManager().UpsertTag(c.stream.Conn().RemotePeer(), "relay-hop-stream", incrementTag)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Decrement the underlying relay connection tag by 1; this is performed when we close the
|
|
|
|
// relayed connection.
|
|
|
|
func (c *Conn) untagHop() {
|
|
|
|
c.host.ConnManager().UpsertTag(c.stream.Conn().RemotePeer(), "relay-hop-stream", decrementTag)
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: is it okay to cast c.Conn().RemotePeer() into a multiaddr? might be "user input"
|
2018-07-04 10:51:47 +00:00
|
|
|
func (c *Conn) RemoteMultiaddr() ma.Multiaddr {
|
2019-10-04 15:21:24 +00:00
|
|
|
// TODO: We should be able to do this directly without converting to/from a string.
|
|
|
|
relayAddr, err := ma.NewComponent(
|
|
|
|
ma.ProtocolWithCode(ma.P_P2P).Name,
|
|
|
|
c.stream.Conn().RemotePeer().Pretty(),
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return ma.Join(c.stream.Conn().RemoteMultiaddr(), relayAddr, circuitAddr)
|
2018-07-04 10:51:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Conn) LocalMultiaddr() ma.Multiaddr {
|
2019-06-09 07:24:20 +00:00
|
|
|
return c.stream.Conn().LocalMultiaddr()
|
2018-07-04 10:51:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Conn) LocalAddr() net.Addr {
|
2019-06-09 07:24:20 +00:00
|
|
|
na, err := manet.ToNetAddr(c.stream.Conn().LocalMultiaddr())
|
2018-07-04 10:51:47 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Error("failed to convert local multiaddr to net addr:", err)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return na
|
|
|
|
}
|