github.com/rclone/rclone@v1.66.1-0.20240517100346-7b89735ae726/lib/proxy/socks.go (about) 1 // Package proxy enables SOCKS5 proxy dialling 2 package proxy 3 4 import ( 5 "fmt" 6 "net" 7 "strings" 8 9 "golang.org/x/net/proxy" 10 ) 11 12 // SOCKS5Dial dials a net.Conn using a SOCKS5 proxy server. 13 // The socks5Proxy address can be in the form of [user:password@]host:port, [user@]host:port or just host:port if no auth is required. 14 // It will optionally take a proxyDialer to dial the SOCKS5 proxy server. If nil is passed, it will use the default net.Dialer. 15 func SOCKS5Dial(network, addr, socks5Proxy string, proxyDialer proxy.Dialer) (net.Conn, error) { 16 17 if proxyDialer == nil { 18 proxyDialer = &net.Dialer{} 19 } 20 var ( 21 proxyAddress string 22 proxyAuth *proxy.Auth 23 ) 24 if credsAndHost := strings.SplitN(socks5Proxy, "@", 2); len(credsAndHost) == 2 { 25 proxyCreds := strings.SplitN(credsAndHost[0], ":", 2) 26 proxyAuth = &proxy.Auth{ 27 User: proxyCreds[0], 28 } 29 if len(proxyCreds) == 2 { 30 proxyAuth.Password = proxyCreds[1] 31 } 32 proxyAddress = credsAndHost[1] 33 } else { 34 proxyAddress = credsAndHost[0] 35 } 36 proxyDialer, err := proxy.SOCKS5("tcp", proxyAddress, proxyAuth, proxyDialer) 37 if err != nil { 38 return nil, fmt.Errorf("failed to create proxy dialer: %w", err) 39 } 40 return proxyDialer.Dial(network, addr) 41 42 }