tun.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  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/taskmonitor"
  10. C "github.com/sagernet/sing-box/constant"
  11. "github.com/sagernet/sing-box/experimental/libbox/platform"
  12. "github.com/sagernet/sing-box/log"
  13. "github.com/sagernet/sing-box/option"
  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. platformInterface platform.Interface
  35. platformOptions option.TunPlatformOptions
  36. }
  37. func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TunInboundOptions, platformInterface platform.Interface) (*Tun, error) {
  38. tunMTU := options.MTU
  39. if tunMTU == 0 {
  40. tunMTU = 9000
  41. }
  42. var udpTimeout time.Duration
  43. if options.UDPTimeout != 0 {
  44. udpTimeout = time.Duration(options.UDPTimeout)
  45. } else {
  46. udpTimeout = C.UDPTimeout
  47. }
  48. includeUID := uidToRange(options.IncludeUID)
  49. if len(options.IncludeUIDRange) > 0 {
  50. var err error
  51. includeUID, err = parseRange(includeUID, options.IncludeUIDRange)
  52. if err != nil {
  53. return nil, E.Cause(err, "parse include_uid_range")
  54. }
  55. }
  56. excludeUID := uidToRange(options.ExcludeUID)
  57. if len(options.ExcludeUIDRange) > 0 {
  58. var err error
  59. excludeUID, err = parseRange(excludeUID, options.ExcludeUIDRange)
  60. if err != nil {
  61. return nil, E.Cause(err, "parse exclude_uid_range")
  62. }
  63. }
  64. return &Tun{
  65. tag: tag,
  66. ctx: ctx,
  67. router: router,
  68. logger: logger,
  69. inboundOptions: options.InboundOptions,
  70. tunOptions: tun.Options{
  71. Name: options.InterfaceName,
  72. MTU: tunMTU,
  73. GSO: options.GSO,
  74. Inet4Address: options.Inet4Address,
  75. Inet6Address: options.Inet6Address,
  76. AutoRoute: options.AutoRoute,
  77. StrictRoute: options.StrictRoute,
  78. IncludeInterface: options.IncludeInterface,
  79. ExcludeInterface: options.ExcludeInterface,
  80. Inet4RouteAddress: options.Inet4RouteAddress,
  81. Inet6RouteAddress: options.Inet6RouteAddress,
  82. Inet4RouteExcludeAddress: options.Inet4RouteExcludeAddress,
  83. Inet6RouteExcludeAddress: options.Inet6RouteExcludeAddress,
  84. IncludeUID: includeUID,
  85. ExcludeUID: excludeUID,
  86. IncludeAndroidUser: options.IncludeAndroidUser,
  87. IncludePackage: options.IncludePackage,
  88. ExcludePackage: options.ExcludePackage,
  89. InterfaceMonitor: router.InterfaceMonitor(),
  90. TableIndex: 2022,
  91. },
  92. endpointIndependentNat: options.EndpointIndependentNat,
  93. udpTimeout: int64(udpTimeout.Seconds()),
  94. stack: options.Stack,
  95. platformInterface: platformInterface,
  96. platformOptions: common.PtrValueOrDefault(options.Platform),
  97. }, nil
  98. }
  99. func uidToRange(uidList option.Listable[uint32]) []ranges.Range[uint32] {
  100. return common.Map(uidList, func(uid uint32) ranges.Range[uint32] {
  101. return ranges.NewSingle(uid)
  102. })
  103. }
  104. func parseRange(uidRanges []ranges.Range[uint32], rangeList []string) ([]ranges.Range[uint32], error) {
  105. for _, uidRange := range rangeList {
  106. if !strings.Contains(uidRange, ":") {
  107. return nil, E.New("missing ':' in range: ", uidRange)
  108. }
  109. subIndex := strings.Index(uidRange, ":")
  110. if subIndex == 0 {
  111. return nil, E.New("missing range start: ", uidRange)
  112. } else if subIndex == len(uidRange)-1 {
  113. return nil, E.New("missing range end: ", uidRange)
  114. }
  115. var start, end uint64
  116. var err error
  117. start, err = strconv.ParseUint(uidRange[:subIndex], 10, 32)
  118. if err != nil {
  119. return nil, E.Cause(err, "parse range start")
  120. }
  121. end, err = strconv.ParseUint(uidRange[subIndex+1:], 10, 32)
  122. if err != nil {
  123. return nil, E.Cause(err, "parse range end")
  124. }
  125. uidRanges = append(uidRanges, ranges.New(uint32(start), uint32(end)))
  126. }
  127. return uidRanges, nil
  128. }
  129. func (t *Tun) Type() string {
  130. return C.TypeTun
  131. }
  132. func (t *Tun) Tag() string {
  133. return t.tag
  134. }
  135. func (t *Tun) Start() error {
  136. if C.IsAndroid && t.platformInterface == nil {
  137. t.tunOptions.BuildAndroidRules(t.router.PackageManager(), t)
  138. }
  139. if t.tunOptions.Name == "" {
  140. t.tunOptions.Name = tun.CalculateInterfaceName("")
  141. }
  142. var (
  143. tunInterface tun.Tun
  144. err error
  145. )
  146. monitor := taskmonitor.New(t.logger, C.DefaultStartTimeout)
  147. monitor.Start("open tun interface")
  148. if t.platformInterface != nil {
  149. tunInterface, err = t.platformInterface.OpenTun(&t.tunOptions, t.platformOptions)
  150. } else {
  151. tunInterface, err = tun.New(t.tunOptions)
  152. }
  153. monitor.Finish()
  154. if err != nil {
  155. return E.Cause(err, "configure tun interface")
  156. }
  157. t.logger.Trace("creating stack")
  158. t.tunIf = tunInterface
  159. t.tunStack, err = tun.NewStack(t.stack, tun.StackOptions{
  160. Context: t.ctx,
  161. Tun: tunInterface,
  162. TunOptions: t.tunOptions,
  163. EndpointIndependentNat: t.endpointIndependentNat,
  164. UDPTimeout: t.udpTimeout,
  165. Handler: t,
  166. Logger: t.logger,
  167. ForwarderBindInterface: t.platformInterface != nil,
  168. InterfaceFinder: t.router.InterfaceFinder(),
  169. })
  170. if err != nil {
  171. return err
  172. }
  173. monitor.Start("initiating tun stack")
  174. err = t.tunStack.Start()
  175. monitor.Finish()
  176. if err != nil {
  177. return err
  178. }
  179. t.logger.Info("started at ", t.tunOptions.Name)
  180. return nil
  181. }
  182. func (t *Tun) Close() error {
  183. return common.Close(
  184. t.tunStack,
  185. t.tunIf,
  186. )
  187. }
  188. func (t *Tun) NewConnection(ctx context.Context, conn net.Conn, upstreamMetadata M.Metadata) error {
  189. ctx = log.ContextWithNewID(ctx)
  190. var metadata adapter.InboundContext
  191. metadata.Inbound = t.tag
  192. metadata.InboundType = C.TypeTun
  193. metadata.Source = upstreamMetadata.Source
  194. metadata.Destination = upstreamMetadata.Destination
  195. metadata.InboundOptions = t.inboundOptions
  196. t.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
  197. t.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
  198. err := t.router.RouteConnection(ctx, conn, metadata)
  199. if err != nil {
  200. t.NewError(ctx, err)
  201. }
  202. return nil
  203. }
  204. func (t *Tun) NewPacketConnection(ctx context.Context, conn N.PacketConn, upstreamMetadata M.Metadata) error {
  205. ctx = log.ContextWithNewID(ctx)
  206. var metadata adapter.InboundContext
  207. metadata.Inbound = t.tag
  208. metadata.InboundType = C.TypeTun
  209. metadata.Source = upstreamMetadata.Source
  210. metadata.Destination = upstreamMetadata.Destination
  211. metadata.InboundOptions = t.inboundOptions
  212. t.logger.InfoContext(ctx, "inbound packet connection from ", metadata.Source)
  213. t.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
  214. err := t.router.RoutePacketConnection(ctx, conn, metadata)
  215. if err != nil {
  216. t.NewError(ctx, err)
  217. }
  218. return nil
  219. }
  220. func (t *Tun) NewError(ctx context.Context, err error) {
  221. NewError(t.logger, ctx, err)
  222. }