tun.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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. )
  21. var _ adapter.Inbound = (*Tun)(nil)
  22. type Tun struct {
  23. tag string
  24. ctx context.Context
  25. router adapter.Router
  26. logger log.Logger
  27. options option.TunInboundOptions
  28. tunFd uintptr
  29. tun *tun.GVisorTun
  30. }
  31. func NewTun(ctx context.Context, router adapter.Router, logger log.Logger, tag string, options option.TunInboundOptions) (*Tun, error) {
  32. return &Tun{
  33. tag: tag,
  34. ctx: ctx,
  35. router: router,
  36. logger: logger,
  37. options: options,
  38. }, nil
  39. }
  40. func (t *Tun) Type() string {
  41. return C.TypeTun
  42. }
  43. func (t *Tun) Tag() string {
  44. return t.tag
  45. }
  46. func (t *Tun) Start() error {
  47. tunName := t.options.InterfaceName
  48. if tunName == "" {
  49. tunName = mkInterfaceName()
  50. }
  51. var mtu uint32
  52. if t.options.MTU != 0 {
  53. mtu = t.options.MTU
  54. } else {
  55. mtu = 1500
  56. }
  57. tunFd, err := tun.Open(tunName)
  58. if err != nil {
  59. return E.Cause(err, "create tun interface")
  60. }
  61. err = tun.Configure(tunName, netip.Prefix(t.options.Inet4Address), netip.Prefix(t.options.Inet6Address), mtu)
  62. if err != nil {
  63. return E.Cause(err, "configure tun interface")
  64. }
  65. t.tunFd = tunFd
  66. t.tun = tun.NewGVisor(t.ctx, tunFd, mtu, t)
  67. err = t.tun.Start()
  68. if err != nil {
  69. return err
  70. }
  71. t.logger.Info("started at ", tunName)
  72. return nil
  73. }
  74. func (t *Tun) Close() error {
  75. return E.Errors(
  76. t.tun.Close(),
  77. os.NewFile(t.tunFd, "tun").Close(),
  78. )
  79. }
  80. func (t *Tun) NewConnection(ctx context.Context, conn net.Conn, upstreamMetadata M.Metadata) error {
  81. t.logger.WithContext(ctx).Info("inbound connection from ", upstreamMetadata.Source)
  82. t.logger.WithContext(ctx).Info("inbound connection to ", upstreamMetadata.Destination)
  83. var metadata adapter.InboundContext
  84. metadata.Inbound = t.tag
  85. metadata.Network = C.NetworkTCP
  86. metadata.Source = upstreamMetadata.Source
  87. metadata.Destination = upstreamMetadata.Destination
  88. return t.router.RouteConnection(ctx, conn, metadata)
  89. }
  90. func (t *Tun) NewPacketConnection(ctx context.Context, conn N.PacketConn, upstreamMetadata M.Metadata) error {
  91. t.logger.WithContext(ctx).Info("inbound packet connection from ", upstreamMetadata.Source)
  92. t.logger.WithContext(ctx).Info("inbound packet connection to ", upstreamMetadata.Destination)
  93. var metadata adapter.InboundContext
  94. metadata.Inbound = t.tag
  95. metadata.Network = C.NetworkUDP
  96. metadata.Source = upstreamMetadata.Source
  97. metadata.Destination = upstreamMetadata.Destination
  98. return t.router.RoutePacketConnection(ctx, conn, metadata)
  99. }
  100. func (t *Tun) NewError(ctx context.Context, err error) {
  101. NewError(t.logger, ctx, err)
  102. }
  103. func mkInterfaceName() (tunName string) {
  104. switch runtime.GOOS {
  105. case "darwin":
  106. tunName = "utun"
  107. default:
  108. tunName = "tun"
  109. }
  110. interfaces, err := net.Interfaces()
  111. if err != nil {
  112. return
  113. }
  114. var tunIndex int
  115. for _, netInterface := range interfaces {
  116. if strings.HasPrefix(netInterface.Name, tunName) {
  117. index, parseErr := strconv.ParseInt(netInterface.Name[len(tunName):], 10, 16)
  118. if parseErr == nil {
  119. tunIndex = int(index) + 1
  120. }
  121. }
  122. }
  123. tunName = F.ToString(tunName, tunIndex)
  124. return
  125. }