inbound.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. package tun
  2. import (
  3. "context"
  4. "net"
  5. "net/netip"
  6. "os"
  7. "runtime"
  8. "strconv"
  9. "strings"
  10. "time"
  11. "github.com/sagernet/sing-box/adapter"
  12. "github.com/sagernet/sing-box/adapter/inbound"
  13. "github.com/sagernet/sing-box/common/taskmonitor"
  14. C "github.com/sagernet/sing-box/constant"
  15. "github.com/sagernet/sing-box/log"
  16. "github.com/sagernet/sing-box/option"
  17. "github.com/sagernet/sing-box/route/rule"
  18. "github.com/sagernet/sing-tun"
  19. "github.com/sagernet/sing/common"
  20. E "github.com/sagernet/sing/common/exceptions"
  21. "github.com/sagernet/sing/common/json/badoption"
  22. M "github.com/sagernet/sing/common/metadata"
  23. N "github.com/sagernet/sing/common/network"
  24. "github.com/sagernet/sing/common/ranges"
  25. "github.com/sagernet/sing/common/x/list"
  26. "github.com/sagernet/sing/service"
  27. "go4.org/netipx"
  28. )
  29. func RegisterInbound(registry *inbound.Registry) {
  30. inbound.Register[option.TunInboundOptions](registry, C.TypeTun, NewInbound)
  31. }
  32. type Inbound struct {
  33. tag string
  34. ctx context.Context
  35. router adapter.Router
  36. networkManager adapter.NetworkManager
  37. logger log.ContextLogger
  38. tunOptions tun.Options
  39. udpTimeout time.Duration
  40. stack string
  41. tunIf tun.Tun
  42. tunStack tun.Stack
  43. platformInterface adapter.PlatformInterface
  44. platformOptions option.TunPlatformOptions
  45. autoRedirect tun.AutoRedirect
  46. routeRuleSet []adapter.RuleSet
  47. routeRuleSetCallback []*list.Element[adapter.RuleSetUpdateCallback]
  48. routeExcludeRuleSet []adapter.RuleSet
  49. routeExcludeRuleSetCallback []*list.Element[adapter.RuleSetUpdateCallback]
  50. routeAddressSet []*netipx.IPSet
  51. routeExcludeAddressSet []*netipx.IPSet
  52. }
  53. func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TunInboundOptions) (adapter.Inbound, error) {
  54. //nolint:staticcheck
  55. if len(options.Inet4Address) > 0 || len(options.Inet6Address) > 0 ||
  56. len(options.Inet4RouteAddress) > 0 || len(options.Inet6RouteAddress) > 0 ||
  57. len(options.Inet4RouteExcludeAddress) > 0 || len(options.Inet6RouteExcludeAddress) > 0 {
  58. return nil, E.New("legacy tun address fields are deprecated in sing-box 1.10.0 and removed in sing-box 1.12.0")
  59. }
  60. //nolint:staticcheck
  61. if options.GSO {
  62. return nil, E.New("GSO option in tun is deprecated in sing-box 1.11.0 and removed in sing-box 1.12.0")
  63. }
  64. address := options.Address
  65. inet4Address := common.Filter(address, func(it netip.Prefix) bool {
  66. return it.Addr().Is4()
  67. })
  68. inet6Address := common.Filter(address, func(it netip.Prefix) bool {
  69. return it.Addr().Is6()
  70. })
  71. routeAddress := options.RouteAddress
  72. inet4RouteAddress := common.Filter(routeAddress, func(it netip.Prefix) bool {
  73. return it.Addr().Is4()
  74. })
  75. inet6RouteAddress := common.Filter(routeAddress, func(it netip.Prefix) bool {
  76. return it.Addr().Is6()
  77. })
  78. routeExcludeAddress := options.RouteExcludeAddress
  79. inet4RouteExcludeAddress := common.Filter(routeExcludeAddress, func(it netip.Prefix) bool {
  80. return it.Addr().Is4()
  81. })
  82. inet6RouteExcludeAddress := common.Filter(routeExcludeAddress, func(it netip.Prefix) bool {
  83. return it.Addr().Is6()
  84. })
  85. platformInterface := service.FromContext[adapter.PlatformInterface](ctx)
  86. tunMTU := options.MTU
  87. enableGSO := C.IsLinux && options.Stack == "gvisor" && platformInterface == nil && tunMTU > 0 && tunMTU < 49152
  88. if tunMTU == 0 {
  89. if platformInterface != nil && platformInterface.UnderNetworkExtension() {
  90. // In Network Extension, when MTU exceeds 4064 (4096-UTUN_IF_HEADROOM_SIZE), the performance of tun will drop significantly, which may be a system bug.
  91. tunMTU = 4064
  92. } else if C.IsAndroid {
  93. // Some Android devices report ENOBUFS when using MTU 65535
  94. tunMTU = 9000
  95. } else {
  96. tunMTU = 65535
  97. }
  98. }
  99. var udpTimeout time.Duration
  100. if options.UDPTimeout != 0 {
  101. udpTimeout = time.Duration(options.UDPTimeout)
  102. } else {
  103. udpTimeout = C.UDPTimeout
  104. }
  105. var err error
  106. includeUID := uidToRange(options.IncludeUID)
  107. if len(options.IncludeUIDRange) > 0 {
  108. includeUID, err = parseRange(includeUID, options.IncludeUIDRange)
  109. if err != nil {
  110. return nil, E.Cause(err, "parse include_uid_range")
  111. }
  112. }
  113. excludeUID := uidToRange(options.ExcludeUID)
  114. if len(options.ExcludeUIDRange) > 0 {
  115. excludeUID, err = parseRange(excludeUID, options.ExcludeUIDRange)
  116. if err != nil {
  117. return nil, E.Cause(err, "parse exclude_uid_range")
  118. }
  119. }
  120. tableIndex := options.IPRoute2TableIndex
  121. if tableIndex == 0 {
  122. tableIndex = tun.DefaultIPRoute2TableIndex
  123. }
  124. ruleIndex := options.IPRoute2RuleIndex
  125. if ruleIndex == 0 {
  126. ruleIndex = tun.DefaultIPRoute2RuleIndex
  127. }
  128. autoRedirectFallbackRuleIndex := options.AutoRedirectFallbackRuleIndex
  129. if autoRedirectFallbackRuleIndex == 0 {
  130. autoRedirectFallbackRuleIndex = tun.DefaultIPRoute2AutoRedirectFallbackRuleIndex
  131. }
  132. inputMark := uint32(options.AutoRedirectInputMark)
  133. if inputMark == 0 {
  134. inputMark = tun.DefaultAutoRedirectInputMark
  135. }
  136. outputMark := uint32(options.AutoRedirectOutputMark)
  137. if outputMark == 0 {
  138. outputMark = tun.DefaultAutoRedirectOutputMark
  139. }
  140. resetMark := uint32(options.AutoRedirectResetMark)
  141. if resetMark == 0 {
  142. resetMark = tun.DefaultAutoRedirectResetMark
  143. }
  144. nfQueue := options.AutoRedirectNFQueue
  145. if nfQueue == 0 {
  146. nfQueue = tun.DefaultAutoRedirectNFQueue
  147. }
  148. var includeMACAddress []net.HardwareAddr
  149. for i, macString := range options.IncludeMACAddress {
  150. mac, macErr := net.ParseMAC(macString)
  151. if macErr != nil {
  152. return nil, E.Cause(macErr, "parse include_mac_address[", i, "]")
  153. }
  154. includeMACAddress = append(includeMACAddress, mac)
  155. }
  156. var excludeMACAddress []net.HardwareAddr
  157. for i, macString := range options.ExcludeMACAddress {
  158. mac, macErr := net.ParseMAC(macString)
  159. if macErr != nil {
  160. return nil, E.Cause(macErr, "parse exclude_mac_address[", i, "]")
  161. }
  162. excludeMACAddress = append(excludeMACAddress, mac)
  163. }
  164. networkManager := service.FromContext[adapter.NetworkManager](ctx)
  165. multiPendingPackets := C.IsDarwin && ((options.Stack == "gvisor" && tunMTU < 32768) || (options.Stack != "gvisor" && options.MTU <= 9000))
  166. inbound := &Inbound{
  167. tag: tag,
  168. ctx: ctx,
  169. router: router,
  170. networkManager: networkManager,
  171. logger: logger,
  172. tunOptions: tun.Options{
  173. Name: options.InterfaceName,
  174. MTU: tunMTU,
  175. GSO: enableGSO,
  176. Inet4Address: inet4Address,
  177. Inet6Address: inet6Address,
  178. AutoRoute: options.AutoRoute,
  179. IPRoute2TableIndex: tableIndex,
  180. IPRoute2RuleIndex: ruleIndex,
  181. IPRoute2AutoRedirectFallbackRuleIndex: autoRedirectFallbackRuleIndex,
  182. AutoRedirectInputMark: inputMark,
  183. AutoRedirectOutputMark: outputMark,
  184. AutoRedirectResetMark: resetMark,
  185. AutoRedirectNFQueue: nfQueue,
  186. ExcludeMPTCP: options.ExcludeMPTCP,
  187. Inet4LoopbackAddress: common.Filter(options.LoopbackAddress, netip.Addr.Is4),
  188. Inet6LoopbackAddress: common.Filter(options.LoopbackAddress, netip.Addr.Is6),
  189. StrictRoute: options.StrictRoute,
  190. IncludeInterface: options.IncludeInterface,
  191. ExcludeInterface: options.ExcludeInterface,
  192. Inet4RouteAddress: inet4RouteAddress,
  193. Inet6RouteAddress: inet6RouteAddress,
  194. Inet4RouteExcludeAddress: inet4RouteExcludeAddress,
  195. Inet6RouteExcludeAddress: inet6RouteExcludeAddress,
  196. IncludeUID: includeUID,
  197. ExcludeUID: excludeUID,
  198. IncludeAndroidUser: options.IncludeAndroidUser,
  199. IncludePackage: options.IncludePackage,
  200. ExcludePackage: options.ExcludePackage,
  201. IncludeMACAddress: includeMACAddress,
  202. ExcludeMACAddress: excludeMACAddress,
  203. InterfaceMonitor: networkManager.InterfaceMonitor(),
  204. EXP_MultiPendingPackets: multiPendingPackets,
  205. },
  206. udpTimeout: udpTimeout,
  207. stack: options.Stack,
  208. platformInterface: platformInterface,
  209. platformOptions: common.PtrValueOrDefault(options.Platform),
  210. }
  211. for _, routeAddressSet := range options.RouteAddressSet {
  212. ruleSet, loaded := router.RuleSet(routeAddressSet)
  213. if !loaded {
  214. return nil, E.New("parse route_address_set: rule-set not found: ", routeAddressSet)
  215. }
  216. inbound.routeRuleSet = append(inbound.routeRuleSet, ruleSet)
  217. }
  218. for _, routeExcludeAddressSet := range options.RouteExcludeAddressSet {
  219. ruleSet, loaded := router.RuleSet(routeExcludeAddressSet)
  220. if !loaded {
  221. return nil, E.New("parse route_exclude_address_set: rule-set not found: ", routeExcludeAddressSet)
  222. }
  223. inbound.routeExcludeRuleSet = append(inbound.routeExcludeRuleSet, ruleSet)
  224. }
  225. if options.AutoRedirect {
  226. if !options.AutoRoute {
  227. return nil, E.New("`auto_route` is required by `auto_redirect`")
  228. }
  229. disableNFTables, dErr := strconv.ParseBool(os.Getenv("DISABLE_NFTABLES"))
  230. inbound.autoRedirect, err = tun.NewAutoRedirect(tun.AutoRedirectOptions{
  231. TunOptions: &inbound.tunOptions,
  232. Context: ctx,
  233. Handler: (*autoRedirectHandler)(inbound),
  234. Logger: logger,
  235. NetworkMonitor: networkManager.NetworkMonitor(),
  236. InterfaceFinder: networkManager.InterfaceFinder(),
  237. TableName: "sing-box",
  238. DisableNFTables: dErr == nil && disableNFTables,
  239. RouteAddressSet: &inbound.routeAddressSet,
  240. RouteExcludeAddressSet: &inbound.routeExcludeAddressSet,
  241. })
  242. if err != nil {
  243. return nil, E.Cause(err, "initialize auto-redirect")
  244. }
  245. if !C.IsAndroid {
  246. inbound.tunOptions.AutoRedirectMarkMode = true
  247. err = networkManager.RegisterAutoRedirectOutputMark(inbound.tunOptions.AutoRedirectOutputMark)
  248. if err != nil {
  249. return nil, err
  250. }
  251. }
  252. }
  253. return inbound, nil
  254. }
  255. func uidToRange(uidList badoption.Listable[uint32]) []ranges.Range[uint32] {
  256. return common.Map(uidList, func(uid uint32) ranges.Range[uint32] {
  257. return ranges.NewSingle(uid)
  258. })
  259. }
  260. func parseRange(uidRanges []ranges.Range[uint32], rangeList []string) ([]ranges.Range[uint32], error) {
  261. for _, uidRange := range rangeList {
  262. if !strings.Contains(uidRange, ":") {
  263. return nil, E.New("missing ':' in range: ", uidRange)
  264. }
  265. subIndex := strings.Index(uidRange, ":")
  266. if subIndex == 0 {
  267. return nil, E.New("missing range start: ", uidRange)
  268. } else if subIndex == len(uidRange)-1 {
  269. return nil, E.New("missing range end: ", uidRange)
  270. }
  271. var start, end uint64
  272. var err error
  273. start, err = strconv.ParseUint(uidRange[:subIndex], 0, 32)
  274. if err != nil {
  275. return nil, E.Cause(err, "parse range start")
  276. }
  277. end, err = strconv.ParseUint(uidRange[subIndex+1:], 0, 32)
  278. if err != nil {
  279. return nil, E.Cause(err, "parse range end")
  280. }
  281. uidRanges = append(uidRanges, ranges.New(uint32(start), uint32(end)))
  282. }
  283. return uidRanges, nil
  284. }
  285. func (t *Inbound) Type() string {
  286. return C.TypeTun
  287. }
  288. func (t *Inbound) Tag() string {
  289. return t.tag
  290. }
  291. func (t *Inbound) Start(stage adapter.StartStage) error {
  292. switch stage {
  293. case adapter.StartStateStart:
  294. if C.IsAndroid && t.platformInterface == nil {
  295. t.tunOptions.BuildAndroidRules(t.networkManager.PackageManager())
  296. }
  297. if t.tunOptions.Name == "" {
  298. t.tunOptions.Name = tun.CalculateInterfaceName("")
  299. }
  300. if t.platformInterface == nil {
  301. t.routeAddressSet = common.FlatMap(t.routeRuleSet, adapter.RuleSet.ExtractIPSet)
  302. for _, routeRuleSet := range t.routeRuleSet {
  303. ipSets := routeRuleSet.ExtractIPSet()
  304. if len(ipSets) == 0 {
  305. t.logger.Warn("route_address_set: no destination IP CIDR rules found in rule-set: ", routeRuleSet.Name())
  306. }
  307. routeRuleSet.IncRef()
  308. t.routeAddressSet = append(t.routeAddressSet, ipSets...)
  309. if t.autoRedirect != nil {
  310. t.routeRuleSetCallback = append(t.routeRuleSetCallback, routeRuleSet.RegisterCallback(t.updateRouteAddressSet))
  311. }
  312. }
  313. t.routeExcludeAddressSet = common.FlatMap(t.routeExcludeRuleSet, adapter.RuleSet.ExtractIPSet)
  314. for _, routeExcludeRuleSet := range t.routeExcludeRuleSet {
  315. ipSets := routeExcludeRuleSet.ExtractIPSet()
  316. if len(ipSets) == 0 {
  317. t.logger.Warn("route_address_set: no destination IP CIDR rules found in rule-set: ", routeExcludeRuleSet.Name())
  318. }
  319. routeExcludeRuleSet.IncRef()
  320. t.routeExcludeAddressSet = append(t.routeExcludeAddressSet, ipSets...)
  321. if t.autoRedirect != nil {
  322. t.routeExcludeRuleSetCallback = append(t.routeExcludeRuleSetCallback, routeExcludeRuleSet.RegisterCallback(t.updateRouteAddressSet))
  323. }
  324. }
  325. }
  326. var (
  327. tunInterface tun.Tun
  328. err error
  329. )
  330. monitor := taskmonitor.New(t.logger, C.StartTimeout)
  331. tunOptions := t.tunOptions
  332. if t.autoRedirect == nil && !(runtime.GOOS == "android" && t.platformInterface != nil) {
  333. for _, ipSet := range t.routeAddressSet {
  334. for _, prefix := range ipSet.Prefixes() {
  335. if prefix.Addr().Is4() {
  336. tunOptions.Inet4RouteAddress = append(tunOptions.Inet4RouteAddress, prefix)
  337. } else {
  338. tunOptions.Inet6RouteAddress = append(tunOptions.Inet6RouteAddress, prefix)
  339. }
  340. }
  341. }
  342. for _, ipSet := range t.routeExcludeAddressSet {
  343. for _, prefix := range ipSet.Prefixes() {
  344. if prefix.Addr().Is4() {
  345. tunOptions.Inet4RouteExcludeAddress = append(tunOptions.Inet4RouteExcludeAddress, prefix)
  346. } else {
  347. tunOptions.Inet6RouteExcludeAddress = append(tunOptions.Inet6RouteExcludeAddress, prefix)
  348. }
  349. }
  350. }
  351. }
  352. monitor.Start("open interface")
  353. if t.platformInterface != nil && t.platformInterface.UsePlatformInterface() {
  354. tunInterface, err = t.platformInterface.OpenInterface(&tunOptions, t.platformOptions)
  355. } else {
  356. if HookBeforeCreatePlatformInterface != nil {
  357. HookBeforeCreatePlatformInterface()
  358. }
  359. tunInterface, err = tun.New(tunOptions)
  360. }
  361. monitor.Finish()
  362. t.tunOptions.Name = tunOptions.Name
  363. if err != nil {
  364. return E.Cause(err, "configure tun interface")
  365. }
  366. t.logger.Trace("creating stack")
  367. t.tunIf = tunInterface
  368. var (
  369. forwarderBindInterface bool
  370. includeAllNetworks bool
  371. )
  372. if t.platformInterface != nil {
  373. forwarderBindInterface = true
  374. includeAllNetworks = t.platformInterface.NetworkExtensionIncludeAllNetworks()
  375. }
  376. tunStack, err := tun.NewStack(t.stack, tun.StackOptions{
  377. Context: t.ctx,
  378. Tun: tunInterface,
  379. TunOptions: t.tunOptions,
  380. UDPTimeout: t.udpTimeout,
  381. Handler: t,
  382. Logger: t.logger,
  383. ForwarderBindInterface: forwarderBindInterface,
  384. InterfaceFinder: t.networkManager.InterfaceFinder(),
  385. IncludeAllNetworks: includeAllNetworks,
  386. })
  387. if err != nil {
  388. return err
  389. }
  390. t.tunStack = tunStack
  391. t.logger.Info("started at ", t.tunOptions.Name)
  392. case adapter.StartStatePostStart:
  393. monitor := taskmonitor.New(t.logger, C.StartTimeout)
  394. monitor.Start("starting tun stack")
  395. err := t.tunStack.Start()
  396. monitor.Finish()
  397. if err != nil {
  398. return E.Cause(err, "starting tun stack")
  399. }
  400. monitor.Start("starting tun interface")
  401. err = t.tunIf.Start()
  402. monitor.Finish()
  403. if err != nil {
  404. return E.Cause(err, "starting TUN interface")
  405. }
  406. if t.autoRedirect != nil {
  407. monitor.Start("initialize auto-redirect")
  408. err := t.autoRedirect.Start()
  409. monitor.Finish()
  410. if err != nil {
  411. return E.Cause(err, "auto-redirect")
  412. }
  413. }
  414. t.routeAddressSet = nil
  415. t.routeExcludeAddressSet = nil
  416. }
  417. return nil
  418. }
  419. func (t *Inbound) updateRouteAddressSet(it adapter.RuleSet) {
  420. t.routeAddressSet = common.FlatMap(t.routeRuleSet, adapter.RuleSet.ExtractIPSet)
  421. t.routeExcludeAddressSet = common.FlatMap(t.routeExcludeRuleSet, adapter.RuleSet.ExtractIPSet)
  422. t.autoRedirect.UpdateRouteAddressSet()
  423. t.routeAddressSet = nil
  424. t.routeExcludeAddressSet = nil
  425. }
  426. func (t *Inbound) Close() error {
  427. return common.Close(
  428. t.tunStack,
  429. t.tunIf,
  430. t.autoRedirect,
  431. )
  432. }
  433. func (t *Inbound) PrepareConnection(network string, source M.Socksaddr, destination M.Socksaddr, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) {
  434. var ipVersion uint8
  435. if !destination.IsIPv6() {
  436. ipVersion = 4
  437. } else {
  438. ipVersion = 6
  439. }
  440. routeDestination, err := t.router.PreMatch(adapter.InboundContext{
  441. Inbound: t.tag,
  442. InboundType: C.TypeTun,
  443. IPVersion: ipVersion,
  444. Network: network,
  445. Source: source,
  446. Destination: destination,
  447. }, routeContext, timeout, false)
  448. if err != nil {
  449. switch {
  450. case rule.IsBypassed(err):
  451. err = nil
  452. case rule.IsRejected(err):
  453. t.logger.Trace("reject ", network, " connection from ", source.AddrString(), " to ", destination.AddrString())
  454. default:
  455. if network == N.NetworkICMP {
  456. t.logger.Warn(E.Cause(err, "link ", network, " connection from ", source.AddrString(), " to ", destination.AddrString()))
  457. }
  458. }
  459. }
  460. return routeDestination, err
  461. }
  462. func (t *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
  463. ctx = log.ContextWithNewID(ctx)
  464. var metadata adapter.InboundContext
  465. metadata.Inbound = t.tag
  466. metadata.InboundType = C.TypeTun
  467. metadata.Source = source
  468. metadata.Destination = destination
  469. t.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
  470. t.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
  471. t.router.RouteConnectionEx(ctx, conn, metadata, onClose)
  472. }
  473. func (t *Inbound) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
  474. ctx = log.ContextWithNewID(ctx)
  475. var metadata adapter.InboundContext
  476. metadata.Inbound = t.tag
  477. metadata.InboundType = C.TypeTun
  478. metadata.Source = source
  479. metadata.Destination = destination
  480. t.logger.InfoContext(ctx, "inbound packet connection from ", metadata.Source)
  481. t.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
  482. t.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
  483. }
  484. type autoRedirectHandler Inbound
  485. func (t *autoRedirectHandler) PrepareConnection(network string, source M.Socksaddr, destination M.Socksaddr, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) {
  486. var ipVersion uint8
  487. if !destination.IsIPv6() {
  488. ipVersion = 4
  489. } else {
  490. ipVersion = 6
  491. }
  492. routeDestination, err := t.router.PreMatch(adapter.InboundContext{
  493. Inbound: t.tag,
  494. InboundType: C.TypeTun,
  495. IPVersion: ipVersion,
  496. Network: network,
  497. Source: source,
  498. Destination: destination,
  499. }, routeContext, timeout, true)
  500. if err != nil {
  501. switch {
  502. case rule.IsBypassed(err):
  503. t.logger.Trace("bypass ", network, " connection from ", source.AddrString(), " to ", destination.AddrString())
  504. case rule.IsRejected(err):
  505. t.logger.Trace("reject ", network, " connection from ", source.AddrString(), " to ", destination.AddrString())
  506. default:
  507. if network == N.NetworkICMP {
  508. t.logger.Warn(E.Cause(err, "link ", network, " connection from ", source.AddrString(), " to ", destination.AddrString()))
  509. }
  510. }
  511. }
  512. return routeDestination, err
  513. }
  514. func (t *autoRedirectHandler) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
  515. ctx = log.ContextWithNewID(ctx)
  516. var metadata adapter.InboundContext
  517. metadata.Inbound = t.tag
  518. metadata.InboundType = C.TypeTun
  519. metadata.Source = source
  520. metadata.Destination = destination
  521. t.logger.InfoContext(ctx, "inbound redirect connection from ", metadata.Source)
  522. t.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
  523. t.router.RouteConnectionEx(ctx, conn, metadata, onClose)
  524. }
  525. func (t *autoRedirectHandler) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
  526. panic("unexcepted")
  527. }