tun.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. //go:build !no_tun
  2. package inbound
  3. import (
  4. "context"
  5. "net"
  6. "net/netip"
  7. "os"
  8. "runtime"
  9. "strconv"
  10. "strings"
  11. "github.com/sagernet/sing-box/adapter"
  12. "github.com/sagernet/sing-box/common/tun"
  13. C "github.com/sagernet/sing-box/constant"
  14. "github.com/sagernet/sing-box/log"
  15. "github.com/sagernet/sing-box/option"
  16. E "github.com/sagernet/sing/common/exceptions"
  17. F "github.com/sagernet/sing/common/format"
  18. M "github.com/sagernet/sing/common/metadata"
  19. N "github.com/sagernet/sing/common/network"
  20. "github.com/sagernet/sing/common/task"
  21. )
  22. var _ adapter.Inbound = (*Tun)(nil)
  23. type Tun struct {
  24. tag string
  25. ctx context.Context
  26. router adapter.Router
  27. logger log.Logger
  28. inboundOptions option.InboundOptions
  29. tunName string
  30. tunMTU uint32
  31. inet4Address netip.Prefix
  32. inet6Address netip.Prefix
  33. autoRoute bool
  34. hijackDNS bool
  35. tunFd uintptr
  36. tun *tun.GVisorTun
  37. }
  38. func NewTun(ctx context.Context, router adapter.Router, logger log.Logger, tag string, options option.TunInboundOptions) (*Tun, error) {
  39. tunName := options.InterfaceName
  40. if tunName == "" {
  41. tunName = mkInterfaceName()
  42. }
  43. tunMTU := options.MTU
  44. if tunMTU == 0 {
  45. tunMTU = 1500
  46. }
  47. return &Tun{
  48. tag: tag,
  49. ctx: ctx,
  50. router: router,
  51. logger: logger,
  52. inboundOptions: options.InboundOptions,
  53. tunName: tunName,
  54. tunMTU: tunMTU,
  55. inet4Address: netip.Prefix(options.Inet4Address),
  56. inet6Address: netip.Prefix(options.Inet6Address),
  57. autoRoute: options.AutoRoute,
  58. hijackDNS: options.HijackDNS,
  59. }, nil
  60. }
  61. func (t *Tun) Type() string {
  62. return C.TypeTun
  63. }
  64. func (t *Tun) Tag() string {
  65. return t.tag
  66. }
  67. func (t *Tun) Start() error {
  68. tunFd, err := tun.Open(t.tunName)
  69. if err != nil {
  70. return E.Cause(err, "create tun interface")
  71. }
  72. err = tun.Configure(t.tunName, t.inet4Address, t.inet6Address, t.tunMTU, t.autoRoute)
  73. if err != nil {
  74. return E.Cause(err, "configure tun interface")
  75. }
  76. t.tunFd = tunFd
  77. t.tun = tun.NewGVisor(t.ctx, tunFd, t.tunMTU, t)
  78. err = t.tun.Start()
  79. if err != nil {
  80. return err
  81. }
  82. t.logger.Info("started at ", t.tunName)
  83. return nil
  84. }
  85. func (t *Tun) Close() error {
  86. err := tun.UnConfigure(t.tunName, t.inet4Address, t.inet6Address, t.autoRoute)
  87. if err != nil {
  88. return err
  89. }
  90. return E.Errors(
  91. t.tun.Close(),
  92. os.NewFile(t.tunFd, "tun").Close(),
  93. )
  94. }
  95. func (t *Tun) NewConnection(ctx context.Context, conn net.Conn, upstreamMetadata M.Metadata) error {
  96. var metadata adapter.InboundContext
  97. metadata.Inbound = t.tag
  98. metadata.Network = C.NetworkTCP
  99. metadata.Source = upstreamMetadata.Source
  100. metadata.Destination = upstreamMetadata.Destination
  101. metadata.SniffEnabled = t.inboundOptions.SniffEnabled
  102. metadata.SniffOverrideDestination = t.inboundOptions.SniffOverrideDestination
  103. metadata.DomainStrategy = C.DomainStrategy(t.inboundOptions.DomainStrategy)
  104. if t.hijackDNS && upstreamMetadata.Destination.Port == 53 {
  105. return task.Run(ctx, func() error {
  106. return NewDNSConnection(ctx, t.router, t.logger, conn, metadata)
  107. })
  108. }
  109. t.logger.WithContext(ctx).Info("inbound connection from ", metadata.Source)
  110. t.logger.WithContext(ctx).Info("inbound connection to ", metadata.Destination)
  111. return t.router.RouteConnection(ctx, conn, metadata)
  112. }
  113. func (t *Tun) NewPacketConnection(ctx context.Context, conn N.PacketConn, upstreamMetadata M.Metadata) error {
  114. var metadata adapter.InboundContext
  115. metadata.Inbound = t.tag
  116. metadata.Network = C.NetworkUDP
  117. metadata.Source = upstreamMetadata.Source
  118. metadata.Destination = upstreamMetadata.Destination
  119. metadata.SniffEnabled = t.inboundOptions.SniffEnabled
  120. metadata.SniffOverrideDestination = t.inboundOptions.SniffOverrideDestination
  121. metadata.DomainStrategy = C.DomainStrategy(t.inboundOptions.DomainStrategy)
  122. if t.hijackDNS && upstreamMetadata.Destination.Port == 53 {
  123. return task.Run(ctx, func() error {
  124. return NewDNSPacketConnection(ctx, t.router, t.logger, conn, metadata)
  125. })
  126. }
  127. t.logger.WithContext(ctx).Info("inbound packet connection from ", metadata.Source)
  128. t.logger.WithContext(ctx).Info("inbound packet connection to ", metadata.Destination)
  129. return t.router.RoutePacketConnection(ctx, conn, metadata)
  130. }
  131. func (t *Tun) NewError(ctx context.Context, err error) {
  132. NewError(t.logger, ctx, err)
  133. }
  134. func mkInterfaceName() (tunName string) {
  135. switch runtime.GOOS {
  136. case "darwin":
  137. tunName = "utun"
  138. default:
  139. tunName = "tun"
  140. }
  141. interfaces, err := net.Interfaces()
  142. if err != nil {
  143. return
  144. }
  145. var tunIndex int
  146. for _, netInterface := range interfaces {
  147. if strings.HasPrefix(netInterface.Name, tunName) {
  148. index, parseErr := strconv.ParseInt(netInterface.Name[len(tunName):], 10, 16)
  149. if parseErr == nil {
  150. tunIndex = int(index) + 1
  151. }
  152. }
  153. }
  154. tunName = F.ToString(tunName, tunIndex)
  155. return
  156. }