system_dialer.go 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. package internet
  2. import (
  3. "context"
  4. "syscall"
  5. "time"
  6. "v2ray.com/core/common/net"
  7. "v2ray.com/core/common/session"
  8. )
  9. var (
  10. effectiveSystemDialer SystemDialer = DefaultSystemDialer{}
  11. )
  12. type SystemDialer interface {
  13. Dial(ctx context.Context, source net.Address, destination net.Destination) (net.Conn, error)
  14. }
  15. type DefaultSystemDialer struct {
  16. }
  17. func getSocketSettings(ctx context.Context) *SocketConfig {
  18. streamSettings := StreamSettingsFromContext(ctx)
  19. if streamSettings != nil && streamSettings.SocketSettings != nil {
  20. return streamSettings.SocketSettings
  21. }
  22. return nil
  23. }
  24. func (DefaultSystemDialer) Dial(ctx context.Context, src net.Address, dest net.Destination) (net.Conn, error) {
  25. dialer := &net.Dialer{
  26. Timeout: time.Second * 60,
  27. DualStack: true,
  28. }
  29. sockopts := getSocketSettings(ctx)
  30. if sockopts != nil {
  31. bindAddress := BindAddressFromContext(ctx)
  32. dialer.Control = func(network, address string, c syscall.RawConn) error {
  33. return c.Control(func(fd uintptr) {
  34. if err := applyOutboundSocketOptions(network, address, fd, sockopts); err != nil {
  35. newError("failed to apply socket options").Base(err).WriteToLog(session.ExportIDToError(ctx))
  36. }
  37. if dest.Network == net.Network_UDP && bindAddress.IsValid() {
  38. if err := bindAddr(fd, bindAddress.Address, bindAddress.Port); err != nil {
  39. newError("failed to bind source address to ", bindAddress).Base(err).WriteToLog(session.ExportIDToError(ctx))
  40. }
  41. }
  42. })
  43. }
  44. }
  45. if src != nil && src != net.AnyIP {
  46. var addr net.Addr
  47. if dest.Network == net.Network_TCP {
  48. addr = &net.TCPAddr{
  49. IP: src.IP(),
  50. Port: 0,
  51. }
  52. } else {
  53. addr = &net.UDPAddr{
  54. IP: src.IP(),
  55. Port: 0,
  56. }
  57. }
  58. dialer.LocalAddr = addr
  59. }
  60. return dialer.DialContext(ctx, dest.Network.SystemString(), dest.NetAddr())
  61. }
  62. type SystemDialerAdapter interface {
  63. Dial(network string, address string) (net.Conn, error)
  64. }
  65. type SimpleSystemDialer struct {
  66. adapter SystemDialerAdapter
  67. }
  68. func WithAdapter(dialer SystemDialerAdapter) SystemDialer {
  69. return &SimpleSystemDialer{
  70. adapter: dialer,
  71. }
  72. }
  73. func (v *SimpleSystemDialer) Dial(ctx context.Context, src net.Address, dest net.Destination) (net.Conn, error) {
  74. return v.adapter.Dial(dest.Network.SystemString(), dest.NetAddr())
  75. }
  76. // UseAlternativeSystemDialer replaces the current system dialer with a given one.
  77. // Caller must ensure there is no race condition.
  78. func UseAlternativeSystemDialer(dialer SystemDialer) {
  79. if dialer == nil {
  80. effectiveSystemDialer = DefaultSystemDialer{}
  81. }
  82. effectiveSystemDialer = dialer
  83. }