Improve network handling and only listen networks we will use
Fixes #290.
This commit is contained in:
parent
70f63b2991
commit
d9e1ebde70
53
client.go
53
client.go
|
@ -225,7 +225,7 @@ func NewClient(cfg *ClientConfig) (cl *Client, err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cl.conns, err = listenAll(allPeerNetworks, cl.config.ListenHost, cl.config.ListenPort, cl.config.ProxyURL, cl.firewallCallback)
|
cl.conns, err = listenAll(cl.listenNetworks(), cl.config.ListenHost, cl.config.ListenPort, cl.config.ProxyURL, cl.firewallCallback)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ func NewClient(cfg *ClientConfig) (cl *Client, err error) {
|
||||||
cl.LocalPort()
|
cl.LocalPort()
|
||||||
|
|
||||||
for _, s := range cl.conns {
|
for _, s := range cl.conns {
|
||||||
if peerNetworkEnabled(s.Addr().Network(), cl.config) {
|
if peerNetworkEnabled(parseNetworkString(s.Addr().Network()), cl.config) {
|
||||||
go cl.acceptConnections(s)
|
go cl.acceptConnections(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,7 +266,7 @@ func (cl *Client) firewallCallback(net.Addr) bool {
|
||||||
return block
|
return block
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cl *Client) enabledPeerNetworks() (ns []string) {
|
func (cl *Client) enabledPeerNetworks() (ns []network) {
|
||||||
for _, n := range allPeerNetworks {
|
for _, n := range allPeerNetworks {
|
||||||
if peerNetworkEnabled(n, cl.config) {
|
if peerNetworkEnabled(n, cl.config) {
|
||||||
ns = append(ns, n)
|
ns = append(ns, n)
|
||||||
|
@ -275,6 +275,31 @@ func (cl *Client) enabledPeerNetworks() (ns []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cl *Client) listenOnNetwork(n network) bool {
|
||||||
|
if n.Ipv4 && cl.config.DisableIPv4 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if n.Ipv6 && cl.config.DisableIPv6 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if n.Tcp && cl.config.DisableTCP {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if n.Udp && cl.config.DisableUTP && cl.config.NoDHT {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cl *Client) listenNetworks() (ns []network) {
|
||||||
|
for _, n := range allPeerNetworks {
|
||||||
|
if cl.listenOnNetwork(n) {
|
||||||
|
ns = append(ns, n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (cl *Client) newDhtServer(conn net.PacketConn) (s *dht.Server, err error) {
|
func (cl *Client) newDhtServer(conn net.PacketConn) (s *dht.Server, err error) {
|
||||||
cfg := dht.ServerConfig{
|
cfg := dht.ServerConfig{
|
||||||
IPBlocklist: cl.ipBlockList,
|
IPBlocklist: cl.ipBlockList,
|
||||||
|
@ -475,26 +500,6 @@ func (cl *Client) dopplegangerAddr(addr string) bool {
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
var allPeerNetworks = []string{"tcp4", "tcp6", "udp4", "udp6"}
|
|
||||||
|
|
||||||
func peerNetworkEnabled(network string, cfg *ClientConfig) bool {
|
|
||||||
c := func(s string) bool {
|
|
||||||
return strings.Contains(network, s)
|
|
||||||
}
|
|
||||||
if cfg.DisableUTP {
|
|
||||||
if c("udp") || c("utp") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if cfg.DisableTCP && c("tcp") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if cfg.DisableIPv6 && c("6") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a connection over UTP or TCP, whichever is first to connect.
|
// Returns a connection over UTP or TCP, whichever is first to connect.
|
||||||
func (cl *Client) dialFirst(ctx context.Context, addr string) dialResult {
|
func (cl *Client) dialFirst(ctx context.Context, addr string) dialResult {
|
||||||
ctx, cancel := context.WithCancel(ctx)
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
|
@ -507,7 +512,7 @@ func (cl *Client) dialFirst(ctx context.Context, addr string) dialResult {
|
||||||
defer cl.unlock()
|
defer cl.unlock()
|
||||||
cl.eachListener(func(s socket) bool {
|
cl.eachListener(func(s socket) bool {
|
||||||
network := s.Addr().Network()
|
network := s.Addr().Network()
|
||||||
if peerNetworkEnabled(network, cl.config) {
|
if peerNetworkEnabled(parseNetworkString(network), cl.config) {
|
||||||
left++
|
left++
|
||||||
go func() {
|
go func() {
|
||||||
cte := cl.config.ConnTracker.Wait(
|
cte := cl.config.ConnTracker.Wait(
|
||||||
|
|
|
@ -239,7 +239,7 @@ func (cn *connection) connectionFlags() (ret string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cn *connection) utp() bool {
|
func (cn *connection) utp() bool {
|
||||||
return isUtpNetwork(cn.network)
|
return parseNetworkString(cn.network).Udp
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inspired by https://github.com/transmission/transmission/wiki/Peer-Status-Text.
|
// Inspired by https://github.com/transmission/transmission/wiki/Peer-Status-Text.
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
package torrent
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
var allPeerNetworks = func() (ret []network) {
|
||||||
|
for _, s := range []string{"tcp4", "tcp6", "udp4", "udp6"} {
|
||||||
|
ret = append(ret, parseNetworkString(s))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}()
|
||||||
|
|
||||||
|
type network struct {
|
||||||
|
Ipv4 bool
|
||||||
|
Ipv6 bool
|
||||||
|
Udp bool
|
||||||
|
Tcp bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n network) String() (ret string) {
|
||||||
|
a := func(b bool, s string) {
|
||||||
|
if b {
|
||||||
|
ret += s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a(n.Udp, "udp")
|
||||||
|
a(n.Tcp, "tcp")
|
||||||
|
a(n.Ipv4, "4")
|
||||||
|
a(n.Ipv6, "6")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseNetworkString(network string) (ret network) {
|
||||||
|
c := func(s string) bool {
|
||||||
|
return strings.Contains(network, s)
|
||||||
|
}
|
||||||
|
ret.Ipv4 = c("4")
|
||||||
|
ret.Ipv6 = c("6")
|
||||||
|
ret.Udp = c("udp")
|
||||||
|
ret.Tcp = c("tcp")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func peerNetworkEnabled(n network, cfg *ClientConfig) bool {
|
||||||
|
if cfg.DisableUTP && n.Udp {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if cfg.DisableTCP && n.Tcp {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if cfg.DisableIPv6 && n.Ipv6 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if cfg.DisableIPv4 && n.Ipv4 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
31
socket.go
31
socket.go
|
@ -2,11 +2,9 @@ package torrent
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/anacrolix/missinggo"
|
"github.com/anacrolix/missinggo"
|
||||||
"github.com/anacrolix/missinggo/perf"
|
"github.com/anacrolix/missinggo/perf"
|
||||||
|
@ -32,24 +30,17 @@ func getProxyDialer(proxyURL string) (proxy.Dialer, error) {
|
||||||
return proxy.FromURL(fixedURL, proxy.Direct)
|
return proxy.FromURL(fixedURL, proxy.Direct)
|
||||||
}
|
}
|
||||||
|
|
||||||
func listen(network, addr, proxyURL string, f firewallCallback) (socket, error) {
|
func listen(n network, addr, proxyURL string, f firewallCallback) (socket, error) {
|
||||||
if isTcpNetwork(network) {
|
switch {
|
||||||
return listenTcp(network, addr, proxyURL)
|
case n.Tcp:
|
||||||
} else if isUtpNetwork(network) {
|
return listenTcp(n.String(), addr, proxyURL)
|
||||||
return listenUtp(network, addr, proxyURL, f)
|
case n.Udp:
|
||||||
} else {
|
return listenUtp(n.String(), addr, proxyURL, f)
|
||||||
panic(fmt.Sprintf("unknown network %q", network))
|
default:
|
||||||
|
panic(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isTcpNetwork(s string) bool {
|
|
||||||
return strings.Contains(s, "tcp")
|
|
||||||
}
|
|
||||||
|
|
||||||
func isUtpNetwork(s string) bool {
|
|
||||||
return strings.Contains(s, "utp") || strings.Contains(s, "udp")
|
|
||||||
}
|
|
||||||
|
|
||||||
func listenTcp(network, address, proxyURL string) (s socket, err error) {
|
func listenTcp(network, address, proxyURL string) (s socket, err error) {
|
||||||
l, err := net.Listen(network, address)
|
l, err := net.Listen(network, address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -90,13 +81,13 @@ func (me tcpSocket) dial(ctx context.Context, addr string) (net.Conn, error) {
|
||||||
return me.d(ctx, addr)
|
return me.d(ctx, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func listenAll(networks []string, getHost func(string) string, port int, proxyURL string, f firewallCallback) ([]socket, error) {
|
func listenAll(networks []network, getHost func(string) string, port int, proxyURL string, f firewallCallback) ([]socket, error) {
|
||||||
if len(networks) == 0 {
|
if len(networks) == 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
var nahs []networkAndHost
|
var nahs []networkAndHost
|
||||||
for _, n := range networks {
|
for _, n := range networks {
|
||||||
nahs = append(nahs, networkAndHost{n, getHost(n)})
|
nahs = append(nahs, networkAndHost{n, getHost(n.String())})
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
ss, retry, err := listenAllRetry(nahs, port, proxyURL, f)
|
ss, retry, err := listenAllRetry(nahs, port, proxyURL, f)
|
||||||
|
@ -107,7 +98,7 @@ func listenAll(networks []string, getHost func(string) string, port int, proxyUR
|
||||||
}
|
}
|
||||||
|
|
||||||
type networkAndHost struct {
|
type networkAndHost struct {
|
||||||
Network string
|
Network network
|
||||||
Host string
|
Host string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue