- }
- dialer := net.Dialer{}
- return tcpSocket{l, func(ctx context.Context, addr string) (conn net.Conn, err error) {
- defer perf.ScopeTimerErr(&err)()
- return dialer.DialContext(ctx, network, addr)
- }}, nil
+ err = controlErr
+ return
+ },
+ // BitTorrent connections manage their own keep-alives.
+ KeepAlive: -1,
+}
+
+func listenTcp(network, address string) (s socket, err error) {
+ l, err := tcpListenConfig.Listen(context.Background(), network, address)
+ return tcpSocket{
+ Listener: l,
+ NetworkDialer: NetworkDialer{
+ Network: network,
+ Dialer: &net.Dialer{
+ // Dialling TCP from a local port limits us to a single outgoing TCP connection to
+ // each remote client. Instead this should be a last resort if we need to use holepunching, and only then to connect to other clients that actually try to holepunch TCP.
+ //LocalAddr: l.Addr(),
+
+ // We don't want fallback, as we explicitly manage the IPv4/IPv6 distinction
+ // ourselves, although it's probably not triggered as I think the network is already
+ // constrained to tcp4 or tcp6 at this point.
+ FallbackDelay: -1,
+ // BitTorrent connections manage their own keep-alives.
+ KeepAlive: tcpListenConfig.KeepAlive,
+ Control: func(network, address string, c syscall.RawConn) (err error) {
+ controlErr := c.Control(func(fd uintptr) {
+ err = setSockNoLinger(fd)
+ if err != nil {
+ // Failing to disable linger is undesirable, but not fatal.
+ log.Printf("error setting linger socket option on tcp socket: %v", err)
+ }
+ err = setReusePortSockOpts(fd)
+ })
+ if err == nil {
+ err = controlErr
+ }
+ return
+ },
+ },
+ },
+ }, err