default.go 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package dialer
  2. import (
  3. "context"
  4. "net"
  5. "runtime"
  6. "time"
  7. "github.com/sagernet/sing-box/adapter"
  8. C "github.com/sagernet/sing-box/constant"
  9. "github.com/sagernet/sing-box/option"
  10. "github.com/sagernet/sing/common/control"
  11. M "github.com/sagernet/sing/common/metadata"
  12. "github.com/database64128/tfo-go"
  13. )
  14. type DefaultDialer struct {
  15. tfo.Dialer
  16. net.ListenConfig
  17. }
  18. func NewDefault(router adapter.Router, options option.DialerOptions) *DefaultDialer {
  19. var dialer net.Dialer
  20. var listener net.ListenConfig
  21. if options.BindInterface != "" {
  22. dialer.Control = control.Append(dialer.Control, control.BindToInterface(router.InterfaceBindManager(), options.BindInterface))
  23. listener.Control = control.Append(listener.Control, control.BindToInterface(router.InterfaceBindManager(), options.BindInterface))
  24. } else if router.AutoDetectInterface() {
  25. if runtime.GOOS == "windows" {
  26. dialer.Control = control.Append(dialer.Control, control.BindToInterfaceIndexFunc(func() int {
  27. return router.AutoDetectInterfaceIndex()
  28. }))
  29. listener.Control = control.Append(listener.Control, control.BindToInterfaceIndexFunc(func() int {
  30. return router.AutoDetectInterfaceIndex()
  31. }))
  32. } else {
  33. dialer.Control = control.Append(dialer.Control, control.BindToInterfaceFunc(router.InterfaceBindManager(), func() string {
  34. return router.AutoDetectInterfaceName()
  35. }))
  36. listener.Control = control.Append(listener.Control, control.BindToInterfaceFunc(router.InterfaceBindManager(), func() string {
  37. return router.AutoDetectInterfaceName()
  38. }))
  39. }
  40. } else if router.DefaultInterface() != "" {
  41. dialer.Control = control.Append(dialer.Control, control.BindToInterface(router.InterfaceBindManager(), router.DefaultInterface()))
  42. listener.Control = control.Append(listener.Control, control.BindToInterface(router.InterfaceBindManager(), router.DefaultInterface()))
  43. }
  44. if options.RoutingMark != 0 {
  45. dialer.Control = control.Append(dialer.Control, control.RoutingMark(options.RoutingMark))
  46. listener.Control = control.Append(listener.Control, control.RoutingMark(options.RoutingMark))
  47. }
  48. if options.ReuseAddr {
  49. listener.Control = control.Append(listener.Control, control.ReuseAddr())
  50. }
  51. if options.ProtectPath != "" {
  52. dialer.Control = control.Append(dialer.Control, control.ProtectPath(options.ProtectPath))
  53. listener.Control = control.Append(listener.Control, control.ProtectPath(options.ProtectPath))
  54. }
  55. if options.ConnectTimeout != 0 {
  56. dialer.Timeout = time.Duration(options.ConnectTimeout)
  57. }
  58. return &DefaultDialer{tfo.Dialer{Dialer: dialer, DisableTFO: !options.TCPFastOpen}, listener}
  59. }
  60. func (d *DefaultDialer) DialContext(ctx context.Context, network string, address M.Socksaddr) (net.Conn, error) {
  61. return d.Dialer.DialContext(ctx, network, address.String())
  62. }
  63. func (d *DefaultDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
  64. return d.ListenConfig.ListenPacket(ctx, C.NetworkUDP, "")
  65. }
  66. func (d *DefaultDialer) Upstream() any {
  67. return &d.Dialer
  68. }