tun.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. //go:build (linux || windows) && !no_gvisor
  2. package inbound
  3. import (
  4. "context"
  5. "net"
  6. "net/netip"
  7. "runtime"
  8. "strconv"
  9. "strings"
  10. "github.com/sagernet/sing-box/adapter"
  11. C "github.com/sagernet/sing-box/constant"
  12. "github.com/sagernet/sing-box/log"
  13. "github.com/sagernet/sing-box/option"
  14. "github.com/sagernet/sing-dns"
  15. "github.com/sagernet/sing-tun"
  16. "github.com/sagernet/sing/common"
  17. E "github.com/sagernet/sing/common/exceptions"
  18. F "github.com/sagernet/sing/common/format"
  19. M "github.com/sagernet/sing/common/metadata"
  20. N "github.com/sagernet/sing/common/network"
  21. )
  22. var _ adapter.Inbound = (*Tun)(nil)
  23. type Tun struct {
  24. tag string
  25. ctx context.Context
  26. router adapter.Router
  27. logger log.ContextLogger
  28. inboundOptions option.InboundOptions
  29. tunName string
  30. tunMTU uint32
  31. inet4Address netip.Prefix
  32. inet6Address netip.Prefix
  33. autoRoute bool
  34. tunIf tun.Tun
  35. tunStack *tun.GVisorTun
  36. }
  37. func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TunInboundOptions) (*Tun, error) {
  38. tunName := options.InterfaceName
  39. if tunName == "" {
  40. tunName = mkInterfaceName()
  41. }
  42. tunMTU := options.MTU
  43. if tunMTU == 0 {
  44. tunMTU = 1500
  45. }
  46. return &Tun{
  47. tag: tag,
  48. ctx: ctx,
  49. router: router,
  50. logger: logger,
  51. inboundOptions: options.InboundOptions,
  52. tunName: tunName,
  53. tunMTU: tunMTU,
  54. inet4Address: options.Inet4Address.Build(),
  55. inet6Address: options.Inet6Address.Build(),
  56. autoRoute: options.AutoRoute,
  57. }, nil
  58. }
  59. func (t *Tun) Type() string {
  60. return C.TypeTun
  61. }
  62. func (t *Tun) Tag() string {
  63. return t.tag
  64. }
  65. func (t *Tun) Start() error {
  66. tunIf, err := tun.Open(t.tunName, t.inet4Address, t.inet6Address, t.tunMTU, t.autoRoute)
  67. if err != nil {
  68. return E.Cause(err, "configure tun interface")
  69. }
  70. t.tunIf = tunIf
  71. t.tunStack = tun.NewGVisor(t.ctx, tunIf, t.tunMTU, t)
  72. err = t.tunStack.Start()
  73. if err != nil {
  74. return err
  75. }
  76. t.logger.Info("started at ", t.tunName)
  77. return nil
  78. }
  79. func (t *Tun) Close() error {
  80. return common.Close(
  81. t.tunStack,
  82. t.tunIf,
  83. )
  84. }
  85. func (t *Tun) NewConnection(ctx context.Context, conn net.Conn, upstreamMetadata M.Metadata) error {
  86. ctx = log.ContextWithNewID(ctx)
  87. var metadata adapter.InboundContext
  88. metadata.Inbound = t.tag
  89. metadata.InboundType = C.TypeTun
  90. metadata.Network = C.NetworkTCP
  91. metadata.Source = upstreamMetadata.Source
  92. metadata.Destination = upstreamMetadata.Destination
  93. metadata.SniffEnabled = t.inboundOptions.SniffEnabled
  94. metadata.SniffOverrideDestination = t.inboundOptions.SniffOverrideDestination
  95. metadata.DomainStrategy = dns.DomainStrategy(t.inboundOptions.DomainStrategy)
  96. t.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
  97. t.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
  98. err := t.router.RouteConnection(ctx, conn, metadata)
  99. if err != nil {
  100. t.NewError(ctx, err)
  101. }
  102. return err
  103. }
  104. func (t *Tun) NewPacketConnection(ctx context.Context, conn N.PacketConn, upstreamMetadata M.Metadata) error {
  105. ctx = log.ContextWithNewID(ctx)
  106. var metadata adapter.InboundContext
  107. metadata.Inbound = t.tag
  108. metadata.InboundType = C.TypeTun
  109. metadata.Network = C.NetworkUDP
  110. metadata.Source = upstreamMetadata.Source
  111. metadata.Destination = upstreamMetadata.Destination
  112. metadata.SniffEnabled = t.inboundOptions.SniffEnabled
  113. metadata.SniffOverrideDestination = t.inboundOptions.SniffOverrideDestination
  114. metadata.DomainStrategy = dns.DomainStrategy(t.inboundOptions.DomainStrategy)
  115. t.logger.InfoContext(ctx, "inbound packet connection from ", metadata.Source)
  116. t.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
  117. err := t.router.RoutePacketConnection(ctx, conn, metadata)
  118. if err != nil {
  119. t.NewError(ctx, err)
  120. }
  121. return err
  122. }
  123. func (t *Tun) NewError(ctx context.Context, err error) {
  124. NewError(t.logger, ctx, err)
  125. }
  126. func mkInterfaceName() (tunName string) {
  127. switch runtime.GOOS {
  128. case "darwin":
  129. tunName = "utun"
  130. default:
  131. tunName = "tun"
  132. }
  133. interfaces, err := net.Interfaces()
  134. if err != nil {
  135. return
  136. }
  137. var tunIndex int
  138. for _, netInterface := range interfaces {
  139. if strings.HasPrefix(netInterface.Name, tunName) {
  140. index, parseErr := strconv.ParseInt(netInterface.Name[len(tunName):], 10, 16)
  141. if parseErr == nil {
  142. tunIndex = int(index) + 1
  143. }
  144. }
  145. }
  146. tunName = F.ToString(tunName, tunIndex)
  147. return
  148. }