tun.go 7.3 KB

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