device_system.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. package wireguard
  2. import (
  3. "context"
  4. "errors"
  5. "net"
  6. "net/netip"
  7. "os"
  8. "runtime"
  9. "sync"
  10. "github.com/sagernet/sing-box/adapter"
  11. "github.com/sagernet/sing-tun"
  12. "github.com/sagernet/sing/common"
  13. M "github.com/sagernet/sing/common/metadata"
  14. N "github.com/sagernet/sing/common/network"
  15. "github.com/sagernet/sing/service"
  16. "github.com/sagernet/wireguard-go/device"
  17. wgTun "github.com/sagernet/wireguard-go/tun"
  18. )
  19. var _ Device = (*systemDevice)(nil)
  20. type systemDevice struct {
  21. options DeviceOptions
  22. dialer N.Dialer
  23. device tun.Tun
  24. batchDevice tun.LinuxTUN
  25. events chan wgTun.Event
  26. closeOnce sync.Once
  27. }
  28. func newSystemDevice(options DeviceOptions) (*systemDevice, error) {
  29. if options.Name == "" {
  30. options.Name = tun.CalculateInterfaceName("wg")
  31. }
  32. return &systemDevice{
  33. options: options,
  34. dialer: options.CreateDialer(options.Name),
  35. events: make(chan wgTun.Event, 1),
  36. }, nil
  37. }
  38. func (w *systemDevice) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
  39. return w.dialer.DialContext(ctx, network, destination)
  40. }
  41. func (w *systemDevice) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
  42. return w.dialer.ListenPacket(ctx, destination)
  43. }
  44. func (w *systemDevice) SetDevice(device *device.Device) {
  45. }
  46. func (w *systemDevice) Start() error {
  47. networkManager := service.FromContext[adapter.NetworkManager](w.options.Context)
  48. tunOptions := tun.Options{
  49. Name: w.options.Name,
  50. Inet4Address: common.Filter(w.options.Address, func(it netip.Prefix) bool {
  51. return it.Addr().Is4()
  52. }),
  53. Inet6Address: common.Filter(w.options.Address, func(it netip.Prefix) bool {
  54. return it.Addr().Is6()
  55. }),
  56. MTU: w.options.MTU,
  57. GSO: true,
  58. InterfaceScope: true,
  59. Inet4RouteAddress: common.Filter(w.options.AllowedAddress, func(it netip.Prefix) bool {
  60. return it.Addr().Is4()
  61. }),
  62. Inet6RouteAddress: common.Filter(w.options.AllowedAddress, func(it netip.Prefix) bool { return it.Addr().Is6() }),
  63. InterfaceMonitor: networkManager.InterfaceMonitor(),
  64. InterfaceFinder: networkManager.InterfaceFinder(),
  65. Logger: w.options.Logger,
  66. }
  67. // works with Linux, macOS with IFSCOPE routes, not tested on Windows
  68. if runtime.GOOS == "darwin" {
  69. tunOptions.AutoRoute = true
  70. }
  71. tunInterface, err := tun.New(tunOptions)
  72. if err != nil {
  73. return err
  74. }
  75. err = tunInterface.Start()
  76. if err != nil {
  77. return err
  78. }
  79. w.options.Logger.Info("started at ", w.options.Name)
  80. w.device = tunInterface
  81. batchTUN, isBatchTUN := tunInterface.(tun.LinuxTUN)
  82. if isBatchTUN {
  83. w.batchDevice = batchTUN
  84. }
  85. w.events <- wgTun.EventUp
  86. return nil
  87. }
  88. func (w *systemDevice) File() *os.File {
  89. return nil
  90. }
  91. func (w *systemDevice) Read(bufs [][]byte, sizes []int, offset int) (count int, err error) {
  92. if w.batchDevice != nil {
  93. count, err = w.batchDevice.BatchRead(bufs, offset-tun.PacketOffset, sizes)
  94. } else {
  95. sizes[0], err = w.device.Read(bufs[0][offset-tun.PacketOffset:])
  96. if err == nil {
  97. count = 1
  98. } else if errors.Is(err, tun.ErrTooManySegments) {
  99. err = wgTun.ErrTooManySegments
  100. }
  101. }
  102. return
  103. }
  104. func (w *systemDevice) Write(bufs [][]byte, offset int) (count int, err error) {
  105. if w.batchDevice != nil {
  106. return w.batchDevice.BatchWrite(bufs, offset)
  107. } else {
  108. for _, packet := range bufs {
  109. if tun.PacketOffset > 0 {
  110. common.ClearArray(packet[offset-tun.PacketOffset : offset])
  111. tun.PacketFillHeader(packet[offset-tun.PacketOffset:], tun.PacketIPVersion(packet[offset:]))
  112. }
  113. _, err = w.device.Write(packet[offset-tun.PacketOffset:])
  114. if err != nil {
  115. return
  116. }
  117. }
  118. }
  119. // WireGuard will not read count
  120. return
  121. }
  122. func (w *systemDevice) Flush() error {
  123. return nil
  124. }
  125. func (w *systemDevice) MTU() (int, error) {
  126. return int(w.options.MTU), nil
  127. }
  128. func (w *systemDevice) Name() (string, error) {
  129. return w.options.Name, nil
  130. }
  131. func (w *systemDevice) Events() <-chan wgTun.Event {
  132. return w.events
  133. }
  134. func (w *systemDevice) Close() error {
  135. close(w.events)
  136. return w.device.Close()
  137. }
  138. func (w *systemDevice) BatchSize() int {
  139. if w.batchDevice != nil {
  140. return w.batchDevice.BatchSize()
  141. }
  142. return 1
  143. }