socks.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. // Package proxy enables SOCKS5 proxy dialling
  2. package proxy
  3. import (
  4. "fmt"
  5. "net"
  6. "strings"
  7. "golang.org/x/net/proxy"
  8. )
  9. // SOCKS5Dial dials a net.Conn using a SOCKS5 proxy server.
  10. // 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.
  11. // It will optionally take a proxyDialer to dial the SOCKS5 proxy server. If nil is passed, it will use the default net.Dialer.
  12. func SOCKS5Dial(network, addr, socks5Proxy string, proxyDialer proxy.Dialer) (net.Conn, error) {
  13. if proxyDialer == nil {
  14. proxyDialer = &net.Dialer{}
  15. }
  16. var (
  17. proxyAddress string
  18. proxyAuth *proxy.Auth
  19. )
  20. if credsAndHost := strings.SplitN(socks5Proxy, "@", 2); len(credsAndHost) == 2 {
  21. proxyCreds := strings.SplitN(credsAndHost[0], ":", 2)
  22. proxyAuth = &proxy.Auth{
  23. User: proxyCreds[0],
  24. }
  25. if len(proxyCreds) == 2 {
  26. proxyAuth.Password = proxyCreds[1]
  27. }
  28. proxyAddress = credsAndHost[1]
  29. } else {
  30. proxyAddress = credsAndHost[0]
  31. }
  32. proxyDialer, err := proxy.SOCKS5("tcp", proxyAddress, proxyAuth, proxyDialer)
  33. if err != nil {
  34. return nil, fmt.Errorf("failed to create proxy dialer: %w", err)
  35. }
  36. return proxyDialer.Dial(network, addr)
  37. }