override.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package dialer
  2. import (
  3. "context"
  4. "crypto/tls"
  5. "net"
  6. C "github.com/sagernet/sing-box/constant"
  7. "github.com/sagernet/sing-box/option"
  8. M "github.com/sagernet/sing/common/metadata"
  9. N "github.com/sagernet/sing/common/network"
  10. "github.com/sagernet/sing/common/uot"
  11. )
  12. var _ N.Dialer = (*OverrideDialer)(nil)
  13. type OverrideDialer struct {
  14. upstream N.Dialer
  15. tlsEnabled bool
  16. tlsConfig tls.Config
  17. uotEnabled bool
  18. }
  19. func NewOverride(upstream N.Dialer, options option.OverrideStreamOptions) N.Dialer {
  20. return &OverrideDialer{
  21. upstream,
  22. options.TLS,
  23. tls.Config{
  24. ServerName: options.TLSServerName,
  25. InsecureSkipVerify: options.TLSInsecure,
  26. },
  27. options.UDPOverTCP,
  28. }
  29. }
  30. func (d *OverrideDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
  31. switch network {
  32. case C.NetworkTCP:
  33. conn, err := d.upstream.DialContext(ctx, C.NetworkTCP, destination)
  34. if err != nil {
  35. return nil, err
  36. }
  37. return tls.Client(conn, &d.tlsConfig), nil
  38. case C.NetworkUDP:
  39. if d.uotEnabled {
  40. tcpConn, err := d.upstream.DialContext(ctx, C.NetworkTCP, destination)
  41. if err != nil {
  42. return nil, err
  43. }
  44. return uot.NewClientConn(tcpConn), nil
  45. }
  46. }
  47. return d.upstream.DialContext(ctx, network, destination)
  48. }
  49. func (d *OverrideDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
  50. if d.uotEnabled {
  51. tcpConn, err := d.upstream.DialContext(ctx, C.NetworkTCP, destination)
  52. if err != nil {
  53. return nil, err
  54. }
  55. return uot.NewClientConn(tcpConn), nil
  56. }
  57. return d.upstream.ListenPacket(ctx, destination)
  58. }
  59. func (d *OverrideDialer) Upstream() any {
  60. return d.upstream
  61. }