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.tcpListener, cl.utpSock, cl.listenAddr, err = listen(
|
||||||
!cl.config.DisableTCP,
|
!cl.config.DisableTCP,
|
||||||
!cl.config.DisableUTP,
|
!cl.config.DisableUTP,
|
||||||
func() string {
|
// We'll listen to IPv4 for TCP even if IPv4 peer connections are
|
||||||
if cl.config.DisableIPv6 {
|
// disabled because we want to ensure peers don't connect to some
|
||||||
return "4"
|
// other process on that port.
|
||||||
} else {
|
ipNetworkSuffix(!cl.config.DisableIPv4, !cl.config.DisableIPv6),
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}(),
|
|
||||||
cl.config.ListenAddr)
|
cl.config.ListenAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
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) {
|
func (cl *Client) acceptConnections(l net.Listener, utp bool) {
|
||||||
cl.mu.Lock()
|
cl.mu.Lock()
|
||||||
defer cl.mu.Unlock()
|
defer cl.mu.Unlock()
|
||||||
|
@ -440,36 +452,21 @@ func (cl *Client) acceptConnections(l net.Listener, utp bool) {
|
||||||
// routine just fucked off.
|
// routine just fucked off.
|
||||||
return
|
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 {
|
if utp {
|
||||||
torrent.Add("accepted utp connections", 1)
|
go torrent.Add("accepted utp connections", 1)
|
||||||
} else {
|
} 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)
|
if cl.rejectAccepted(conn) {
|
||||||
remoteIP := missinggo.AddrIP(conn.RemoteAddr())
|
go torrent.Add("rejected accepted connections", 1)
|
||||||
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)
|
|
||||||
conn.Close()
|
conn.Close()
|
||||||
continue
|
} else {
|
||||||
}
|
|
||||||
go cl.incomingConnection(conn, utp)
|
go cl.incomingConnection(conn, utp)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cl *Client) incomingConnection(nc net.Conn, utp bool) {
|
func (cl *Client) incomingConnection(nc net.Conn, utp bool) {
|
||||||
|
@ -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) {
|
func (cl *Client) dialTCP(ctx context.Context, addr string) (c net.Conn, err error) {
|
||||||
d := net.Dialer{
|
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(),
|
// 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)
|
countDialResult(err)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.(*net.TCPConn).SetLinger(0)
|
c.(*net.TCPConn).SetLinger(0)
|
||||||
|
@ -535,8 +535,37 @@ func (cl *Client) dialTCP(ctx context.Context, addr string) (c net.Conn, err err
|
||||||
return
|
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) {
|
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)
|
countDialResult(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package torrent
|
package torrent
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -171,7 +172,7 @@ func TestUTPRawConn(t *testing.T) {
|
||||||
s, err := NewUtpSocket("udp", "")
|
s, err := NewUtpSocket("udp", "")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
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)
|
require.NoError(t, err)
|
||||||
defer utpPeer.Close()
|
defer utpPeer.Close()
|
||||||
peer, err := net.ListenPacket("udp", ":0")
|
peer, err := net.ListenPacket("udp", ":0")
|
||||||
|
|
|
@ -79,6 +79,8 @@ type Config struct {
|
||||||
|
|
||||||
IPBlocklist iplist.Ranger
|
IPBlocklist iplist.Ranger
|
||||||
DisableIPv6 bool `long:"disable-ipv6"`
|
DisableIPv6 bool `long:"disable-ipv6"`
|
||||||
|
DisableIPv4 bool
|
||||||
|
DisableIPv4Peers bool
|
||||||
// Perform logging and any other behaviour that will help debug.
|
// Perform logging and any other behaviour that will help debug.
|
||||||
Debug bool `help:"enable debugging"`
|
Debug bool `help:"enable debugging"`
|
||||||
|
|
||||||
|
|
4
utp.go
4
utp.go
|
@ -13,6 +13,6 @@ type utpSocket interface {
|
||||||
Accept() (net.Conn, error)
|
Accept() (net.Conn, error)
|
||||||
Addr() net.Addr
|
Addr() net.Addr
|
||||||
// net.Dialer but there's no interface.
|
// net.Dialer but there's no interface.
|
||||||
DialContext(ctx context.Context, addr string) (net.Conn, error)
|
DialContext(ctx context.Context, network, addr string) (net.Conn, error)
|
||||||
Dial(addr string) (net.Conn, error)
|
// Dial(addr string) (net.Conn, error)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue