tun.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. package inbound
  2. import (
  3. "context"
  4. "net"
  5. "strconv"
  6. "strings"
  7. "time"
  8. "github.com/sagernet/sing-box/adapter"
  9. "github.com/sagernet/sing-box/common/canceler"
  10. C "github.com/sagernet/sing-box/constant"
  11. "github.com/sagernet/sing-box/log"
  12. "github.com/sagernet/sing-box/option"
  13. "github.com/sagernet/sing-dns"
  14. "github.com/sagernet/sing-tun"
  15. "github.com/sagernet/sing/common"
  16. E "github.com/sagernet/sing/common/exceptions"
  17. M "github.com/sagernet/sing/common/metadata"
  18. N "github.com/sagernet/sing/common/network"
  19. "github.com/sagernet/sing/common/ranges"
  20. )
  21. var _ adapter.Inbound = (*Tun)(nil)
  22. type Tun struct {
  23. tag string
  24. ctx context.Context
  25. router adapter.Router
  26. logger log.ContextLogger
  27. inboundOptions option.InboundOptions
  28. tunOptions tun.Options
  29. endpointIndependentNat bool
  30. udpTimeout int64
  31. stack string
  32. tunIf tun.Tun
  33. tunStack tun.Stack
  34. }
  35. func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TunInboundOptions) (*Tun, error) {
  36. tunName := options.InterfaceName
  37. if tunName == "" {
  38. tunName = tun.DefaultInterfaceName()
  39. }
  40. tunMTU := options.MTU
  41. if tunMTU == 0 {
  42. tunMTU = 1500
  43. }
  44. var udpTimeout int64
  45. if options.UDPTimeout != 0 {
  46. udpTimeout = options.UDPTimeout
  47. } else {
  48. udpTimeout = int64(C.UDPTimeout.Seconds())
  49. }
  50. includeUID := uidToRange(options.IncludeUID)
  51. if len(options.IncludeUIDRange) > 0 {
  52. var err error
  53. includeUID, err = parseRange(includeUID, options.IncludeUIDRange)
  54. if err != nil {
  55. return nil, E.Cause(err, "parse include_uid_range")
  56. }
  57. }
  58. excludeUID := uidToRange(options.ExcludeUID)
  59. if len(options.ExcludeUIDRange) > 0 {
  60. var err error
  61. excludeUID, err = parseRange(excludeUID, options.ExcludeUIDRange)
  62. if err != nil {
  63. return nil, E.Cause(err, "parse exclude_uid_range")
  64. }
  65. }
  66. return &Tun{
  67. tag: tag,
  68. ctx: ctx,
  69. router: router,
  70. logger: logger,
  71. inboundOptions: options.InboundOptions,
  72. tunOptions: tun.Options{
  73. Name: tunName,
  74. MTU: tunMTU,
  75. Inet4Address: options.Inet4Address.Build(),
  76. Inet6Address: options.Inet6Address.Build(),
  77. AutoRoute: options.AutoRoute,
  78. StrictRoute: options.StrictRoute,
  79. IncludeUID: includeUID,
  80. ExcludeUID: excludeUID,
  81. IncludeAndroidUser: options.IncludeAndroidUser,
  82. IncludePackage: options.IncludePackage,
  83. ExcludePackage: options.ExcludePackage,
  84. InterfaceMonitor: router.InterfaceMonitor(),
  85. },
  86. endpointIndependentNat: options.EndpointIndependentNat,
  87. udpTimeout: udpTimeout,
  88. stack: options.Stack,
  89. }, nil
  90. }
  91. func uidToRange(uidList option.Listable[uint32]) []ranges.Range[uint32] {
  92. return common.Map(uidList, func(uid uint32) ranges.Range[uint32] {
  93. return ranges.NewSingle(uid)
  94. })
  95. }
  96. func parseRange(uidRanges []ranges.Range[uint32], rangeList []string) ([]ranges.Range[uint32], error) {
  97. for _, uidRange := range rangeList {
  98. if !strings.Contains(uidRange, ":") {
  99. return nil, E.New("missing ':' in range: ", uidRange)
  100. }
  101. subIndex := strings.Index(uidRange, ":")
  102. if subIndex == 0 {
  103. return nil, E.New("missing range start: ", uidRange)
  104. } else if subIndex == len(uidRange)-1 {
  105. return nil, E.New("missing range end: ", uidRange)
  106. }
  107. var start, end uint64
  108. var err error
  109. start, err = strconv.ParseUint(uidRange[:subIndex], 10, 32)
  110. if err != nil {
  111. return nil, E.Cause(err, "parse range start")
  112. }
  113. end, err = strconv.ParseUint(uidRange[subIndex+1:], 10, 32)
  114. if err != nil {
  115. return nil, E.Cause(err, "parse range end")
  116. }
  117. uidRanges = append(uidRanges, ranges.New(uint32(start), uint32(end)))
  118. }
  119. return uidRanges, nil
  120. }
  121. func (t *Tun) Type() string {
  122. return C.TypeTun
  123. }
  124. func (t *Tun) Tag() string {
  125. return t.tag
  126. }
  127. func (t *Tun) Start() error {
  128. if C.IsAndroid {
  129. t.tunOptions.BuildAndroidRules(t.router.PackageManager(), t)
  130. }
  131. tunIf, err := tun.Open(t.tunOptions)
  132. if err != nil {
  133. return E.Cause(err, "configure tun interface")
  134. }
  135. t.tunIf = tunIf
  136. t.tunStack, err = tun.NewStack(t.ctx, t.stack, tunIf, t.tunOptions.MTU, t.endpointIndependentNat, t.udpTimeout, t)
  137. if err != nil {
  138. return err
  139. }
  140. err = t.tunStack.Start()
  141. if err != nil {
  142. return err
  143. }
  144. t.logger.Info("started at ", t.tunOptions.Name)
  145. return nil
  146. }
  147. func (t *Tun) Close() error {
  148. return common.Close(
  149. t.tunStack,
  150. t.tunIf,
  151. )
  152. }
  153. func (t *Tun) NewConnection(ctx context.Context, conn net.Conn, upstreamMetadata M.Metadata) error {
  154. ctx = log.ContextWithNewID(ctx)
  155. var metadata adapter.InboundContext
  156. metadata.Inbound = t.tag
  157. metadata.InboundType = C.TypeTun
  158. metadata.Source = upstreamMetadata.Source
  159. metadata.Destination = upstreamMetadata.Destination
  160. metadata.SniffEnabled = t.inboundOptions.SniffEnabled
  161. metadata.SniffOverrideDestination = t.inboundOptions.SniffOverrideDestination
  162. metadata.DomainStrategy = dns.DomainStrategy(t.inboundOptions.DomainStrategy)
  163. t.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
  164. t.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
  165. err := t.router.RouteConnection(ctx, conn, metadata)
  166. if err != nil {
  167. t.NewError(ctx, err)
  168. }
  169. return err
  170. }
  171. func (t *Tun) NewPacketConnection(ctx context.Context, conn N.PacketConn, upstreamMetadata M.Metadata) error {
  172. ctx = log.ContextWithNewID(ctx)
  173. if tun.NeedTimeoutFromContext(ctx) {
  174. ctx, conn = canceler.NewPacketConn(ctx, conn, time.Duration(t.udpTimeout)*time.Second)
  175. }
  176. var metadata adapter.InboundContext
  177. metadata.Inbound = t.tag
  178. metadata.InboundType = C.TypeTun
  179. metadata.Source = upstreamMetadata.Source
  180. metadata.Destination = upstreamMetadata.Destination
  181. metadata.SniffEnabled = t.inboundOptions.SniffEnabled
  182. metadata.SniffOverrideDestination = t.inboundOptions.SniffOverrideDestination
  183. metadata.DomainStrategy = dns.DomainStrategy(t.inboundOptions.DomainStrategy)
  184. t.logger.InfoContext(ctx, "inbound packet connection from ", metadata.Source)
  185. t.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
  186. err := t.router.RoutePacketConnection(ctx, conn, metadata)
  187. if err != nil {
  188. t.NewError(ctx, err)
  189. }
  190. return err
  191. }
  192. func (t *Tun) NewError(ctx context.Context, err error) {
  193. NewError(t.logger, ctx, err)
  194. }