tun.go 6.5 KB

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