Don't expose Peer network through RemoteAddr
This commit is contained in:
parent
955e337b78
commit
9f9953be52
19
client.go
19
client.go
|
@ -677,7 +677,7 @@ func (cl *Client) initiateProtocolHandshakes(
|
||||||
nc net.Conn,
|
nc net.Conn,
|
||||||
t *Torrent,
|
t *Torrent,
|
||||||
outgoing, encryptHeader bool,
|
outgoing, encryptHeader bool,
|
||||||
remoteAddr net.Addr,
|
remoteAddr PeerRemoteAddr,
|
||||||
network, connString string,
|
network, connString string,
|
||||||
) (
|
) (
|
||||||
c *PeerConn, err error,
|
c *PeerConn, err error,
|
||||||
|
@ -699,7 +699,7 @@ func (cl *Client) initiateProtocolHandshakes(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns nil connection and nil error if no connection could be established for valid reasons.
|
// Returns nil connection and nil error if no connection could be established for valid reasons.
|
||||||
func (cl *Client) establishOutgoingConnEx(t *Torrent, addr net.Addr, obfuscatedHeader bool) (*PeerConn, error) {
|
func (cl *Client) establishOutgoingConnEx(t *Torrent, addr PeerRemoteAddr, obfuscatedHeader bool) (*PeerConn, error) {
|
||||||
dialCtx, cancel := context.WithTimeout(context.Background(), func() time.Duration {
|
dialCtx, cancel := context.WithTimeout(context.Background(), func() time.Duration {
|
||||||
cl.rLock()
|
cl.rLock()
|
||||||
defer cl.rUnlock()
|
defer cl.rUnlock()
|
||||||
|
@ -723,7 +723,7 @@ func (cl *Client) establishOutgoingConnEx(t *Torrent, addr net.Addr, obfuscatedH
|
||||||
|
|
||||||
// Returns nil connection and nil error if no connection could be established
|
// Returns nil connection and nil error if no connection could be established
|
||||||
// for valid reasons.
|
// for valid reasons.
|
||||||
func (cl *Client) establishOutgoingConn(t *Torrent, addr net.Addr) (c *PeerConn, err error) {
|
func (cl *Client) establishOutgoingConn(t *Torrent, addr PeerRemoteAddr) (c *PeerConn, err error) {
|
||||||
torrent.Add("establish outgoing connection", 1)
|
torrent.Add("establish outgoing connection", 1)
|
||||||
obfuscatedHeaderFirst := cl.config.HeaderObfuscationPolicy.Preferred
|
obfuscatedHeaderFirst := cl.config.HeaderObfuscationPolicy.Preferred
|
||||||
c, err = cl.establishOutgoingConnEx(t, addr, obfuscatedHeaderFirst)
|
c, err = cl.establishOutgoingConnEx(t, addr, obfuscatedHeaderFirst)
|
||||||
|
@ -748,7 +748,7 @@ func (cl *Client) establishOutgoingConn(t *Torrent, addr net.Addr) (c *PeerConn,
|
||||||
|
|
||||||
// Called to dial out and run a connection. The addr we're given is already
|
// Called to dial out and run a connection. The addr we're given is already
|
||||||
// considered half-open.
|
// considered half-open.
|
||||||
func (cl *Client) outgoingConnection(t *Torrent, addr net.Addr, ps PeerSource, trusted bool) {
|
func (cl *Client) outgoingConnection(t *Torrent, addr PeerRemoteAddr, ps PeerSource, trusted bool) {
|
||||||
cl.dialRateLimiter.Wait(context.Background())
|
cl.dialRateLimiter.Wait(context.Background())
|
||||||
c, err := cl.establishOutgoingConn(t, addr)
|
c, err := cl.establishOutgoingConn(t, addr)
|
||||||
cl.lock()
|
cl.lock()
|
||||||
|
@ -967,7 +967,7 @@ func (cl *Client) sendInitialMessages(conn *PeerConn, torrent *Torrent) {
|
||||||
// that might be used to cache pending writes. Assuming 512KiB cached for
|
// that might be used to cache pending writes. Assuming 512KiB cached for
|
||||||
// sending, for 16KiB chunks.
|
// sending, for 16KiB chunks.
|
||||||
Reqq: 1 << 5,
|
Reqq: 1 << 5,
|
||||||
YourIp: pp.CompactIp(addrIpOrNil(conn.RemoteAddr)),
|
YourIp: pp.CompactIp(conn.remoteIp()),
|
||||||
Encryption: cl.config.HeaderObfuscationPolicy.Preferred || !cl.config.HeaderObfuscationPolicy.RequirePreferred,
|
Encryption: cl.config.HeaderObfuscationPolicy.Preferred || !cl.config.HeaderObfuscationPolicy.RequirePreferred,
|
||||||
Port: cl.incomingPeerPort(),
|
Port: cl.incomingPeerPort(),
|
||||||
MetadataSize: torrent.metadataSize(),
|
MetadataSize: torrent.metadataSize(),
|
||||||
|
@ -1062,7 +1062,7 @@ func (cl *Client) gotMetadataExtensionMsg(payload []byte, t *Torrent, c *PeerCon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cl *Client) badPeerAddr(addr net.Addr) bool {
|
func (cl *Client) badPeerAddr(addr PeerRemoteAddr) bool {
|
||||||
if ipa, ok := tryIpPortFromNetAddr(addr); ok {
|
if ipa, ok := tryIpPortFromNetAddr(addr); ok {
|
||||||
return cl.badPeerIPPort(ipa.IP, ipa.Port)
|
return cl.badPeerIPPort(ipa.IP, ipa.Port)
|
||||||
}
|
}
|
||||||
|
@ -1099,7 +1099,8 @@ func (cl *Client) newTorrent(ih metainfo.Hash, specStorage storage.ClientImpl) (
|
||||||
peers: prioritizedPeers{
|
peers: prioritizedPeers{
|
||||||
om: btree.New(32),
|
om: btree.New(32),
|
||||||
getPrio: func(p PeerInfo) peerPriority {
|
getPrio: func(p PeerInfo) peerPriority {
|
||||||
return bep40PriorityIgnoreError(cl.publicAddr(addrIpOrNil(p.Addr)), p.addr())
|
ipPort := p.addr()
|
||||||
|
return bep40PriorityIgnoreError(cl.publicAddr(ipPort.IP), ipPort)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
conns: make(map[*PeerConn]struct{}, 2*cl.config.EstablishedConnsPerTorrent),
|
conns: make(map[*PeerConn]struct{}, 2*cl.config.EstablishedConnsPerTorrent),
|
||||||
|
@ -1366,7 +1367,7 @@ func (cl *Client) banPeerIP(ip net.IP) {
|
||||||
cl.badPeerIPs[ip.String()] = struct{}{}
|
cl.badPeerIPs[ip.String()] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cl *Client) newConnection(nc net.Conn, outgoing bool, remoteAddr net.Addr, network, connString string) (c *PeerConn) {
|
func (cl *Client) newConnection(nc net.Conn, outgoing bool, remoteAddr PeerRemoteAddr, network, connString string) (c *PeerConn) {
|
||||||
c = &PeerConn{
|
c = &PeerConn{
|
||||||
Peer: Peer{
|
Peer: Peer{
|
||||||
outgoing: outgoing,
|
outgoing: outgoing,
|
||||||
|
@ -1483,7 +1484,7 @@ func (cl *Client) ListenAddrs() (ret []net.Addr) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cl *Client) onBadAccept(addr net.Addr) {
|
func (cl *Client) onBadAccept(addr PeerRemoteAddr) {
|
||||||
ipa, ok := tryIpPortFromNetAddr(addr)
|
ipa, ok := tryIpPortFromNetAddr(addr)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
|
|
17
ipport.go
17
ipport.go
|
@ -56,12 +56,15 @@ func (me ipPortAddr) String() string {
|
||||||
return net.JoinHostPort(me.IP.String(), strconv.FormatInt(int64(me.Port), 10))
|
return net.JoinHostPort(me.IP.String(), strconv.FormatInt(int64(me.Port), 10))
|
||||||
}
|
}
|
||||||
|
|
||||||
func tryIpPortFromNetAddr(na net.Addr) (ret ipPortAddr, ok bool) {
|
func tryIpPortFromNetAddr(addr PeerRemoteAddr) (ipPortAddr, bool) {
|
||||||
ret.IP = addrIpOrNil(na)
|
ok := true
|
||||||
if ret.IP == nil {
|
host, port, err := net.SplitHostPort(addr.String())
|
||||||
return
|
if err != nil {
|
||||||
|
ok = false
|
||||||
}
|
}
|
||||||
ret.Port = addrPortOrZero(na)
|
portI64, err := strconv.ParseInt(port, 10, 0)
|
||||||
ok = true
|
if err != nil {
|
||||||
return
|
ok = false
|
||||||
|
}
|
||||||
|
return ipPortAddr{net.ParseIP(host), int(portI64)}, ok
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package torrent
|
package torrent
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
|
||||||
|
|
||||||
"github.com/anacrolix/dht/v2/krpc"
|
"github.com/anacrolix/dht/v2/krpc"
|
||||||
|
|
||||||
"github.com/anacrolix/torrent/peer_protocol"
|
"github.com/anacrolix/torrent/peer_protocol"
|
||||||
|
@ -11,7 +9,7 @@ import (
|
||||||
// Peer connection info, handed about publicly.
|
// Peer connection info, handed about publicly.
|
||||||
type PeerInfo struct {
|
type PeerInfo struct {
|
||||||
Id [20]byte
|
Id [20]byte
|
||||||
Addr net.Addr
|
Addr PeerRemoteAddr
|
||||||
Source PeerSource
|
Source PeerSource
|
||||||
// Peer is known to support encryption.
|
// Peer is known to support encryption.
|
||||||
SupportsEncryption bool
|
SupportsEncryption bool
|
||||||
|
@ -41,5 +39,6 @@ func (me *PeerInfo) FromPex(na krpc.NodeAddr, fs peer_protocol.PexPeerFlags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (me PeerInfo) addr() IpPort {
|
func (me PeerInfo) addr() IpPort {
|
||||||
return IpPort{IP: addrIpOrNil(me.Addr), Port: uint16(addrPortOrZero(me.Addr))}
|
ipPort, _ := tryIpPortFromNetAddr(me.Addr)
|
||||||
|
return IpPort{ipPort.IP, uint16(ipPort.Port)}
|
||||||
}
|
}
|
||||||
|
|
15
peerconn.go
15
peerconn.go
|
@ -42,6 +42,10 @@ type peerRequestState struct {
|
||||||
data []byte
|
data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PeerRemoteAddr interface {
|
||||||
|
String() string
|
||||||
|
}
|
||||||
|
|
||||||
type Peer struct {
|
type Peer struct {
|
||||||
// First to ensure 64-bit alignment for atomics. See #262.
|
// First to ensure 64-bit alignment for atomics. See #262.
|
||||||
_stats ConnStats
|
_stats ConnStats
|
||||||
|
@ -52,7 +56,7 @@ type Peer struct {
|
||||||
|
|
||||||
outgoing bool
|
outgoing bool
|
||||||
network string
|
network string
|
||||||
RemoteAddr net.Addr
|
RemoteAddr PeerRemoteAddr
|
||||||
// True if the connection is operating over MSE obfuscation.
|
// True if the connection is operating over MSE obfuscation.
|
||||||
headerEncrypted bool
|
headerEncrypted bool
|
||||||
cryptoMethod mse.CryptoMethod
|
cryptoMethod mse.CryptoMethod
|
||||||
|
@ -169,7 +173,7 @@ func (cn *Peer) expectingChunks() bool {
|
||||||
|
|
||||||
// Returns true if the connection is over IPv6.
|
// Returns true if the connection is over IPv6.
|
||||||
func (cn *PeerConn) ipv6() bool {
|
func (cn *PeerConn) ipv6() bool {
|
||||||
ip := addrIpOrNil(cn.RemoteAddr)
|
ip := cn.remoteIp()
|
||||||
if ip.To4() != nil {
|
if ip.To4() != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -1626,7 +1630,8 @@ func (c *Peer) peerPriority() (peerPriority, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Peer) remoteIp() net.IP {
|
func (c *Peer) remoteIp() net.IP {
|
||||||
return addrIpOrNil(c.RemoteAddr)
|
host, _, _ := net.SplitHostPort(c.RemoteAddr.String())
|
||||||
|
return net.ParseIP(host)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Peer) remoteIpPort() IpPort {
|
func (c *Peer) remoteIpPort() IpPort {
|
||||||
|
@ -1642,7 +1647,7 @@ func (c *PeerConn) pexPeerFlags() pp.PexPeerFlags {
|
||||||
if c.outgoing {
|
if c.outgoing {
|
||||||
f |= pp.PexOutgoingConn
|
f |= pp.PexOutgoingConn
|
||||||
}
|
}
|
||||||
if c.RemoteAddr != nil && strings.Contains(c.RemoteAddr.Network(), "udp") {
|
if c.utp() {
|
||||||
f |= pp.PexSupportsUtp
|
f |= pp.PexSupportsUtp
|
||||||
}
|
}
|
||||||
return f
|
return f
|
||||||
|
@ -1650,7 +1655,7 @@ func (c *PeerConn) pexPeerFlags() pp.PexPeerFlags {
|
||||||
|
|
||||||
// This returns the address to use if we want to dial the peer again. It incorporates the peer's
|
// This returns the address to use if we want to dial the peer again. It incorporates the peer's
|
||||||
// advertised listen port.
|
// advertised listen port.
|
||||||
func (c *PeerConn) dialAddr() net.Addr {
|
func (c *PeerConn) dialAddr() PeerRemoteAddr {
|
||||||
if !c.outgoing && c.PeerListenPort != 0 {
|
if !c.outgoing && c.PeerListenPort != 0 {
|
||||||
switch addr := c.RemoteAddr.(type) {
|
switch addr := c.RemoteAddr.(type) {
|
||||||
case *net.TCPAddr:
|
case *net.TCPAddr:
|
||||||
|
|
|
@ -159,10 +159,10 @@ func TestConnPexPeerFlags(t *testing.T) {
|
||||||
{&PeerConn{Peer: Peer{outgoing: false, PeerPrefersEncryption: true}}, pp.PexPrefersEncryption},
|
{&PeerConn{Peer: Peer{outgoing: false, PeerPrefersEncryption: true}}, pp.PexPrefersEncryption},
|
||||||
{&PeerConn{Peer: Peer{outgoing: true, PeerPrefersEncryption: false}}, pp.PexOutgoingConn},
|
{&PeerConn{Peer: Peer{outgoing: true, PeerPrefersEncryption: false}}, pp.PexOutgoingConn},
|
||||||
{&PeerConn{Peer: Peer{outgoing: true, PeerPrefersEncryption: true}}, pp.PexOutgoingConn | pp.PexPrefersEncryption},
|
{&PeerConn{Peer: Peer{outgoing: true, PeerPrefersEncryption: true}}, pp.PexOutgoingConn | pp.PexPrefersEncryption},
|
||||||
{&PeerConn{Peer: Peer{RemoteAddr: udpAddr}}, pp.PexSupportsUtp},
|
{&PeerConn{Peer: Peer{RemoteAddr: udpAddr, network: udpAddr.Network()}}, pp.PexSupportsUtp},
|
||||||
{&PeerConn{Peer: Peer{RemoteAddr: udpAddr, outgoing: true}}, pp.PexOutgoingConn | pp.PexSupportsUtp},
|
{&PeerConn{Peer: Peer{RemoteAddr: udpAddr, network: udpAddr.Network(), outgoing: true}}, pp.PexOutgoingConn | pp.PexSupportsUtp},
|
||||||
{&PeerConn{Peer: Peer{RemoteAddr: tcpAddr, outgoing: true}}, pp.PexOutgoingConn},
|
{&PeerConn{Peer: Peer{RemoteAddr: tcpAddr, network: tcpAddr.Network(), outgoing: true}}, pp.PexOutgoingConn},
|
||||||
{&PeerConn{Peer: Peer{RemoteAddr: tcpAddr}}, 0},
|
{&PeerConn{Peer: Peer{RemoteAddr: tcpAddr, network: tcpAddr.Network()}}, 0},
|
||||||
}
|
}
|
||||||
for i, tc := range testcases {
|
for i, tc := range testcases {
|
||||||
f := tc.conn.pexPeerFlags()
|
f := tc.conn.pexPeerFlags()
|
||||||
|
@ -184,22 +184,22 @@ func TestConnPexEvent(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
pexAdd,
|
pexAdd,
|
||||||
&PeerConn{Peer: Peer{RemoteAddr: udpAddr}},
|
&PeerConn{Peer: Peer{RemoteAddr: udpAddr, network: udpAddr.Network()}},
|
||||||
pexEvent{pexAdd, udpAddr, pp.PexSupportsUtp},
|
pexEvent{pexAdd, udpAddr, pp.PexSupportsUtp},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pexDrop,
|
pexDrop,
|
||||||
&PeerConn{Peer: Peer{RemoteAddr: tcpAddr, outgoing: true, PeerListenPort: dialTcpAddr.Port}},
|
&PeerConn{Peer: Peer{RemoteAddr: tcpAddr, network: tcpAddr.Network(), outgoing: true, PeerListenPort: dialTcpAddr.Port}},
|
||||||
pexEvent{pexDrop, tcpAddr, pp.PexOutgoingConn},
|
pexEvent{pexDrop, tcpAddr, pp.PexOutgoingConn},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pexAdd,
|
pexAdd,
|
||||||
&PeerConn{Peer: Peer{RemoteAddr: tcpAddr, PeerListenPort: dialTcpAddr.Port}},
|
&PeerConn{Peer: Peer{RemoteAddr: tcpAddr, network: tcpAddr.Network(), PeerListenPort: dialTcpAddr.Port}},
|
||||||
pexEvent{pexAdd, dialTcpAddr, 0},
|
pexEvent{pexAdd, dialTcpAddr, 0},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pexDrop,
|
pexDrop,
|
||||||
&PeerConn{Peer: Peer{RemoteAddr: udpAddr, PeerListenPort: dialUdpAddr.Port}},
|
&PeerConn{Peer: Peer{RemoteAddr: udpAddr, network: udpAddr.Network(), PeerListenPort: dialUdpAddr.Port}},
|
||||||
pexEvent{pexDrop, dialUdpAddr, pp.PexSupportsUtp},
|
pexEvent{pexDrop, dialUdpAddr, pp.PexSupportsUtp},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
14
pex.go
14
pex.go
|
@ -25,7 +25,7 @@ const (
|
||||||
// represents a single connection (t=pexAdd) or disconnection (t=pexDrop) event
|
// represents a single connection (t=pexAdd) or disconnection (t=pexDrop) event
|
||||||
type pexEvent struct {
|
type pexEvent struct {
|
||||||
t pexEventType
|
t pexEventType
|
||||||
addr net.Addr
|
addr PeerRemoteAddr
|
||||||
f pp.PexPeerFlags
|
f pp.PexPeerFlags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ func (me *pexMsgFactory) DeltaLen() int {
|
||||||
type addrKey string
|
type addrKey string
|
||||||
|
|
||||||
// Returns the key to use to identify a given addr in the factory.
|
// Returns the key to use to identify a given addr in the factory.
|
||||||
func (me *pexMsgFactory) addrKey(addr net.Addr) addrKey {
|
func (me *pexMsgFactory) addrKey(addr PeerRemoteAddr) addrKey {
|
||||||
return addrKey(addr.String())
|
return addrKey(addr.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,12 +161,10 @@ func (me *pexMsgFactory) PexMsg() pp.PexMsg {
|
||||||
|
|
||||||
// Convert an arbitrary torrent peer Addr into one that can be represented by the compact addr
|
// Convert an arbitrary torrent peer Addr into one that can be represented by the compact addr
|
||||||
// format.
|
// format.
|
||||||
func nodeAddr(addr net.Addr) (_ krpc.NodeAddr, ok bool) {
|
func nodeAddr(addr PeerRemoteAddr) (krpc.NodeAddr, bool) {
|
||||||
ipport, ok := tryIpPortFromNetAddr(addr)
|
ipport, _ := tryIpPortFromNetAddr(addr)
|
||||||
if !ok {
|
ok := ipport.IP != nil
|
||||||
return
|
return krpc.NodeAddr{IP: shortestIP(ipport.IP), Port: ipport.Port}, ok
|
||||||
}
|
|
||||||
return krpc.NodeAddr{IP: shortestIP(ipport.IP), Port: ipport.Port}, true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// mainly for the krpc marshallers
|
// mainly for the krpc marshallers
|
||||||
|
|
Loading…
Reference in New Issue