Fixes #290.
}
}
- 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 {
return
}
cl.LocalPort()
for _, s := range cl.conns {
- if peerNetworkEnabled(s.Addr().Network(), cl.config) {
+ if peerNetworkEnabled(parseNetworkString(s.Addr().Network()), cl.config) {
go cl.acceptConnections(s)
}
}
return block
}
-func (cl *Client) enabledPeerNetworks() (ns []string) {
+func (cl *Client) enabledPeerNetworks() (ns []network) {
for _, n := range allPeerNetworks {
if peerNetworkEnabled(n, cl.config) {
ns = append(ns, n)
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) {
cfg := dht.ServerConfig{
IPBlocklist: cl.ipBlockList,
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.
func (cl *Client) dialFirst(ctx context.Context, addr string) dialResult {
ctx, cancel := context.WithCancel(ctx)
defer cl.unlock()
cl.eachListener(func(s socket) bool {
network := s.Addr().Network()
- if peerNetworkEnabled(network, cl.config) {
+ if peerNetworkEnabled(parseNetworkString(network), cl.config) {
left++
go func() {
cte := cl.config.ConnTracker.Wait(
}
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.
--- /dev/null
+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
+}
import (
"context"
- "fmt"
"net"
"net/url"
"strconv"
- "strings"
"github.com/anacrolix/missinggo"
"github.com/anacrolix/missinggo/perf"
return proxy.FromURL(fixedURL, proxy.Direct)
}
-func listen(network, addr, proxyURL string, f firewallCallback) (socket, error) {
- if isTcpNetwork(network) {
- return listenTcp(network, addr, proxyURL)
- } else if isUtpNetwork(network) {
- return listenUtp(network, addr, proxyURL, f)
- } else {
- panic(fmt.Sprintf("unknown network %q", network))
+func listen(n network, addr, proxyURL string, f firewallCallback) (socket, error) {
+ switch {
+ case n.Tcp:
+ return listenTcp(n.String(), addr, proxyURL)
+ case n.Udp:
+ return listenUtp(n.String(), addr, proxyURL, f)
+ 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) {
l, err := net.Listen(network, address)
if err != nil {
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 {
return nil, nil
}
var nahs []networkAndHost
for _, n := range networks {
- nahs = append(nahs, networkAndHost{n, getHost(n)})
+ nahs = append(nahs, networkAndHost{n, getHost(n.String())})
}
for {
ss, retry, err := listenAllRetry(nahs, port, proxyURL, f)
}
type networkAndHost struct {
- Network string
+ Network network
Host string
}