Add support for disabling IPv4 and IPv4 peers
This commit is contained in:
parent
066cdd520b
commit
b92e8b7814
95
client.go
95
client.go
|
@ -309,13 +309,10 @@ func NewClient(cfg *Config) (cl *Client, err error) {
|
|||
cl.tcpListener, cl.utpSock, cl.listenAddr, err = listen(
|
||||
!cl.config.DisableTCP,
|
||||
!cl.config.DisableUTP,
|
||||
func() string {
|
||||
if cl.config.DisableIPv6 {
|
||||
return "4"
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}(),
|
||||
// We'll listen to IPv4 for TCP even if IPv4 peer connections are
|
||||
// disabled because we want to ensure peers don't connect to some
|
||||
// other process on that port.
|
||||
ipNetworkSuffix(!cl.config.DisableIPv4, !cl.config.DisableIPv6),
|
||||
cl.config.ListenAddr)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -419,6 +416,21 @@ func (cl *Client) waitAccept() {
|
|||
}
|
||||
}
|
||||
|
||||
func (cl *Client) rejectAccepted(conn net.Conn) bool {
|
||||
ra := conn.RemoteAddr()
|
||||
rip := missinggo.AddrIP(ra)
|
||||
if cl.config.DisableIPv4Peers && rip.To4() != nil {
|
||||
return true
|
||||
}
|
||||
if cl.config.DisableIPv4 && len(rip) == net.IPv4len {
|
||||
return true
|
||||
}
|
||||
if cl.config.DisableIPv6 && len(rip) == net.IPv6len && rip.To4() == nil {
|
||||
return true
|
||||
}
|
||||
return cl.badPeerIPPort(rip, missinggo.AddrPort(ra))
|
||||
}
|
||||
|
||||
func (cl *Client) acceptConnections(l net.Listener, utp bool) {
|
||||
cl.mu.Lock()
|
||||
defer cl.mu.Unlock()
|
||||
|
@ -440,37 +452,22 @@ func (cl *Client) acceptConnections(l net.Listener, utp bool) {
|
|||
// routine just fucked off.
|
||||
return
|
||||
}
|
||||
log.Fmsg("accepted connection from %s", conn.RemoteAddr()).AddValue(debugLogValue).Log(cl.logger)
|
||||
go torrent.Add(fmt.Sprintf("accepted conn remote IP len=%d", len(missinggo.AddrIP(conn.RemoteAddr()))), 1)
|
||||
go torrent.Add(fmt.Sprintf("accepted conn network=%s", conn.RemoteAddr().Network()), 1)
|
||||
if utp {
|
||||
torrent.Add("accepted utp connections", 1)
|
||||
go torrent.Add("accepted utp connections", 1)
|
||||
} else {
|
||||
torrent.Add("accepted tcp connections", 1)
|
||||
go torrent.Add("accepted tcp connections", 1)
|
||||
}
|
||||
torrent.Add(fmt.Sprintf("accepted conn with network %q", conn.RemoteAddr().Network()), 1)
|
||||
remoteIP := missinggo.AddrIP(conn.RemoteAddr())
|
||||
if remoteIP.To4() != nil {
|
||||
torrent.Add("accepted conn from ipv4 address", 1)
|
||||
} else if remoteIP.To16() != nil {
|
||||
torrent.Add("accepted conn from ipv6 address", 1)
|
||||
} else {
|
||||
torrent.Add("accepted conn from unknown ip address type", 1)
|
||||
}
|
||||
if cl.config.Debug {
|
||||
log.Printf("accepted connection from %s", conn.RemoteAddr())
|
||||
}
|
||||
reject := cl.badPeerIPPort(
|
||||
missinggo.AddrIP(conn.RemoteAddr()),
|
||||
missinggo.AddrPort(conn.RemoteAddr()))
|
||||
if reject {
|
||||
if cl.config.Debug {
|
||||
log.Printf("rejecting connection from %s", conn.RemoteAddr())
|
||||
}
|
||||
torrent.Add("rejected accepted connection", 1)
|
||||
if cl.rejectAccepted(conn) {
|
||||
go torrent.Add("rejected accepted connections", 1)
|
||||
conn.Close()
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
go cl.incomingConnection(conn, utp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (cl *Client) incomingConnection(nc net.Conn, utp bool) {
|
||||
defer nc.Close()
|
||||
|
@ -524,9 +521,12 @@ func (cl *Client) dopplegangerAddr(addr string) bool {
|
|||
|
||||
func (cl *Client) dialTCP(ctx context.Context, addr string) (c net.Conn, err error) {
|
||||
d := net.Dialer{
|
||||
// Can't bind to the listen address, even though we intend to create an
|
||||
// endpoint pair that is distinct. Oh well.
|
||||
|
||||
// LocalAddr: cl.tcpListener.Addr(),
|
||||
}
|
||||
c, err = d.DialContext(ctx, "tcp", addr)
|
||||
c, err = d.DialContext(ctx, "tcp"+ipNetworkSuffix(!cl.config.DisableIPv4 && !cl.config.DisableIPv4Peers, !cl.config.DisableIPv6), addr)
|
||||
countDialResult(err)
|
||||
if err == nil {
|
||||
c.(*net.TCPConn).SetLinger(0)
|
||||
|
@ -535,8 +535,37 @@ func (cl *Client) dialTCP(ctx context.Context, addr string) (c net.Conn, err err
|
|||
return
|
||||
}
|
||||
|
||||
func (cl *Client) utpDialNetwork() string {
|
||||
// We want to restrict the addr resolve inside the utp library to the
|
||||
// correct network, since the utp Socket may be listening to a broader
|
||||
// network for DHT purposes or otherwise.
|
||||
if !cl.config.DisableIPv4Peers {
|
||||
return ""
|
||||
}
|
||||
n := cl.utpSock.Addr().Network()
|
||||
switch n {
|
||||
case "udp", "udp4", "udp6":
|
||||
return "udp6"
|
||||
default:
|
||||
panic(n)
|
||||
}
|
||||
}
|
||||
|
||||
func ipNetworkSuffix(allowIpv4, allowIpv6 bool) string {
|
||||
switch {
|
||||
case allowIpv4 && allowIpv6:
|
||||
return ""
|
||||
case allowIpv4 && !allowIpv6:
|
||||
return "4"
|
||||
case !allowIpv4 && allowIpv6:
|
||||
return "6"
|
||||
default:
|
||||
panic("unhandled ip network combination")
|
||||
}
|
||||
}
|
||||
|
||||
func (cl *Client) dialUTP(ctx context.Context, addr string) (c net.Conn, err error) {
|
||||
c, err = cl.utpSock.DialContext(ctx, addr)
|
||||
c, err = cl.utpSock.DialContext(ctx, cl.utpDialNetwork(), addr)
|
||||
countDialResult(err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package torrent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -171,7 +172,7 @@ func TestUTPRawConn(t *testing.T) {
|
|||
s, err := NewUtpSocket("udp", "")
|
||||
require.NoError(t, err)
|
||||
defer s.Close()
|
||||
utpPeer, err := s.Dial(fmt.Sprintf("localhost:%d", missinggo.AddrPort(l.Addr())))
|
||||
utpPeer, err := s.DialContext(context.Background(), "", fmt.Sprintf("localhost:%d", missinggo.AddrPort(l.Addr())))
|
||||
require.NoError(t, err)
|
||||
defer utpPeer.Close()
|
||||
peer, err := net.ListenPacket("udp", ":0")
|
||||
|
|
|
@ -79,6 +79,8 @@ type Config struct {
|
|||
|
||||
IPBlocklist iplist.Ranger
|
||||
DisableIPv6 bool `long:"disable-ipv6"`
|
||||
DisableIPv4 bool
|
||||
DisableIPv4Peers bool
|
||||
// Perform logging and any other behaviour that will help debug.
|
||||
Debug bool `help:"enable debugging"`
|
||||
|
||||
|
|
4
utp.go
4
utp.go
|
@ -13,6 +13,6 @@ type utpSocket interface {
|
|||
Accept() (net.Conn, error)
|
||||
Addr() net.Addr
|
||||
// net.Dialer but there's no interface.
|
||||
DialContext(ctx context.Context, addr string) (net.Conn, error)
|
||||
Dial(addr string) (net.Conn, error)
|
||||
DialContext(ctx context.Context, network, addr string) (net.Conn, error)
|
||||
// Dial(addr string) (net.Conn, error)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue