tun.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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. IncludeUID: includeUID,
  79. ExcludeUID: excludeUID,
  80. IncludeAndroidUser: options.IncludeAndroidUser,
  81. IncludePackage: options.IncludePackage,
  82. ExcludePackage: options.ExcludePackage,
  83. InterfaceMonitor: router.InterfaceMonitor(),
  84. TableIndex: 2022,
  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.stack, tun.StackOptions{
  137. Context: t.ctx,
  138. Tun: tunIf,
  139. MTU: t.tunOptions.MTU,
  140. Name: t.tunOptions.Name,
  141. Inet4Address: t.tunOptions.Inet4Address,
  142. Inet6Address: t.tunOptions.Inet6Address,
  143. EndpointIndependentNat: t.endpointIndependentNat,
  144. UDPTimeout: t.udpTimeout,
  145. Handler: t,
  146. Logger: t.logger,
  147. })
  148. if err != nil {
  149. return err
  150. }
  151. err = t.tunStack.Start()
  152. if err != nil {
  153. return err
  154. }
  155. t.logger.Info("started at ", t.tunOptions.Name)
  156. return nil
  157. }
  158. func (t *Tun) Close() error {
  159. return common.Close(
  160. t.tunStack,
  161. t.tunIf,
  162. )
  163. }
  164. func (t *Tun) NewConnection(ctx context.Context, conn net.Conn, upstreamMetadata M.Metadata) error {
  165. ctx = log.ContextWithNewID(ctx)
  166. var metadata adapter.InboundContext
  167. metadata.Inbound = t.tag
  168. metadata.InboundType = C.TypeTun
  169. metadata.Source = upstreamMetadata.Source
  170. metadata.Destination = upstreamMetadata.Destination
  171. metadata.InboundOptions = t.inboundOptions
  172. t.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
  173. t.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
  174. err := t.router.RouteConnection(ctx, conn, metadata)
  175. if err != nil {
  176. t.NewError(ctx, err)
  177. }
  178. return nil
  179. }
  180. func (t *Tun) NewPacketConnection(ctx context.Context, conn N.PacketConn, upstreamMetadata M.Metadata) error {
  181. ctx = log.ContextWithNewID(ctx)
  182. if tun.NeedTimeoutFromContext(ctx) {
  183. ctx, conn = canceler.NewPacketConn(ctx, conn, time.Duration(t.udpTimeout)*time.Second)
  184. }
  185. var metadata adapter.InboundContext
  186. metadata.Inbound = t.tag
  187. metadata.InboundType = C.TypeTun
  188. metadata.Source = upstreamMetadata.Source
  189. metadata.Destination = upstreamMetadata.Destination
  190. metadata.InboundOptions = t.inboundOptions
  191. t.logger.InfoContext(ctx, "inbound packet connection from ", metadata.Source)
  192. t.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
  193. err := t.router.RoutePacketConnection(ctx, conn, metadata)
  194. if err != nil {
  195. t.NewError(ctx, err)
  196. }
  197. return nil
  198. }
  199. func (t *Tun) NewError(ctx context.Context, err error) {
  200. NewError(t.logger, ctx, err)
  201. }