tun.go 5.0 KB

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