lib/connections: Try TCP punchthrough (fixes #4259) (#5753)

This commit is contained in:
Audrius Butkevicius
2020-06-16 09:17:07 +02:00
committed by GitHub
parent d09c8f0d0a
commit f619a7f4cc
14 changed files with 288 additions and 150 deletions
+20
View File
@@ -13,6 +13,7 @@ import (
"net"
"time"
"github.com/syncthing/syncthing/lib/connections/registry"
"golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
"golang.org/x/net/proxy"
@@ -121,3 +122,22 @@ func dialContextWithFallback(ctx context.Context, fallback proxy.ContextDialer,
func DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
return dialContextWithFallback(ctx, proxy.Direct, network, addr)
}
// DialContextReusePort tries dialing via proxy if a proxy is configured, and falls back to
// a direct connection reusing the port from the connections registry, if no proxy is defined, or connecting via proxy
// fails. If the context has a timeout, the timeout might be applied twice.
func DialContextReusePort(ctx context.Context, network, addr string) (net.Conn, error) {
dialer := &net.Dialer{
Control: ReusePortControl,
}
localAddrInterface := registry.Get(network, tcpAddrLess)
if localAddrInterface != nil {
if addr, ok := localAddrInterface.(*net.TCPAddr); !ok {
return nil, errUnexpectedInterfaceType
} else {
dialer.LocalAddr = addr
}
}
return dialContextWithFallback(ctx, dialer, network, addr)
}