system_dialer.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package internet
  2. import (
  3. "context"
  4. "net"
  5. "time"
  6. v2net "v2ray.com/core/common/net"
  7. )
  8. var (
  9. effectiveSystemDialer SystemDialer
  10. )
  11. type SystemDialer interface {
  12. Dial(ctx context.Context, source v2net.Address, destination v2net.Destination) (net.Conn, error)
  13. }
  14. type DefaultSystemDialer struct {
  15. }
  16. func (v *DefaultSystemDialer) Dial(ctx context.Context, src v2net.Address, dest v2net.Destination) (net.Conn, error) {
  17. dialer := &net.Dialer{
  18. Timeout: time.Second * 60,
  19. DualStack: true,
  20. }
  21. if src != nil && src != v2net.AnyIP {
  22. var addr net.Addr
  23. if dest.Network == v2net.Network_TCP {
  24. addr = &net.TCPAddr{
  25. IP: src.IP(),
  26. Port: 0,
  27. }
  28. } else {
  29. addr = &net.UDPAddr{
  30. IP: src.IP(),
  31. Port: 0,
  32. }
  33. }
  34. dialer.LocalAddr = addr
  35. }
  36. return dialer.DialContext(ctx, dest.Network.SystemString(), dest.NetAddr())
  37. }
  38. type SystemDialerAdapter interface {
  39. Dial(network string, address string) (net.Conn, error)
  40. }
  41. type SimpleSystemDialer struct {
  42. adapter SystemDialerAdapter
  43. }
  44. func WithAdapter(dialer SystemDialerAdapter) SystemDialer {
  45. return &SimpleSystemDialer{
  46. adapter: dialer,
  47. }
  48. }
  49. func (v *SimpleSystemDialer) Dial(ctx context.Context, src v2net.Address, dest v2net.Destination) (net.Conn, error) {
  50. return v.adapter.Dial(dest.Network.SystemString(), dest.NetAddr())
  51. }
  52. // UseAlternativeSystemDialer replaces the current system dialer with a given one.
  53. // Caller must ensure there is no race condition.
  54. func UseAlternativeSystemDialer(dialer SystemDialer) {
  55. effectiveSystemDialer = dialer
  56. }
  57. func init() {
  58. effectiveSystemDialer = &DefaultSystemDialer{}
  59. }