device_system.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package wireguard
  2. import (
  3. "context"
  4. "errors"
  5. "net"
  6. "net/netip"
  7. "os"
  8. "sync"
  9. "github.com/sagernet/sing-box/adapter"
  10. "github.com/sagernet/sing-box/common/dialer"
  11. "github.com/sagernet/sing-box/option"
  12. "github.com/sagernet/sing-tun"
  13. "github.com/sagernet/sing/common"
  14. E "github.com/sagernet/sing/common/exceptions"
  15. M "github.com/sagernet/sing/common/metadata"
  16. N "github.com/sagernet/sing/common/network"
  17. wgTun "github.com/sagernet/wireguard-go/tun"
  18. )
  19. var _ Device = (*SystemDevice)(nil)
  20. type SystemDevice struct {
  21. dialer N.Dialer
  22. device tun.Tun
  23. batchDevice tun.LinuxTUN
  24. name string
  25. mtu uint32
  26. inet4Addresses []netip.Prefix
  27. inet6Addresses []netip.Prefix
  28. gso bool
  29. events chan wgTun.Event
  30. closeOnce sync.Once
  31. }
  32. func NewSystemDevice(router adapter.Router, interfaceName string, localPrefixes []netip.Prefix, mtu uint32, gso bool) (*SystemDevice, error) {
  33. var inet4Addresses []netip.Prefix
  34. var inet6Addresses []netip.Prefix
  35. for _, prefixes := range localPrefixes {
  36. if prefixes.Addr().Is4() {
  37. inet4Addresses = append(inet4Addresses, prefixes)
  38. } else {
  39. inet6Addresses = append(inet6Addresses, prefixes)
  40. }
  41. }
  42. if interfaceName == "" {
  43. interfaceName = tun.CalculateInterfaceName("wg")
  44. }
  45. return &SystemDevice{
  46. dialer: common.Must1(dialer.NewDefault(router, option.DialerOptions{
  47. BindInterface: interfaceName,
  48. })),
  49. name: interfaceName,
  50. mtu: mtu,
  51. inet4Addresses: inet4Addresses,
  52. inet6Addresses: inet6Addresses,
  53. gso: gso,
  54. events: make(chan wgTun.Event, 1),
  55. }, nil
  56. }
  57. func (w *SystemDevice) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
  58. return w.dialer.DialContext(ctx, network, destination)
  59. }
  60. func (w *SystemDevice) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
  61. return w.dialer.ListenPacket(ctx, destination)
  62. }
  63. func (w *SystemDevice) Inet4Address() netip.Addr {
  64. if len(w.inet4Addresses) == 0 {
  65. return netip.Addr{}
  66. }
  67. return w.inet4Addresses[0].Addr()
  68. }
  69. func (w *SystemDevice) Inet6Address() netip.Addr {
  70. if len(w.inet6Addresses) == 0 {
  71. return netip.Addr{}
  72. }
  73. return w.inet6Addresses[0].Addr()
  74. }
  75. func (w *SystemDevice) Start() error {
  76. tunInterface, err := tun.New(tun.Options{
  77. Name: w.name,
  78. Inet4Address: w.inet4Addresses,
  79. Inet6Address: w.inet6Addresses,
  80. MTU: w.mtu,
  81. GSO: w.gso,
  82. })
  83. if err != nil {
  84. return err
  85. }
  86. w.device = tunInterface
  87. if w.gso {
  88. batchTUN, isBatchTUN := tunInterface.(tun.LinuxTUN)
  89. if !isBatchTUN {
  90. tunInterface.Close()
  91. return E.New("GSO is not supported on current platform")
  92. }
  93. w.batchDevice = batchTUN
  94. }
  95. w.events <- wgTun.EventUp
  96. return nil
  97. }
  98. func (w *SystemDevice) File() *os.File {
  99. return nil
  100. }
  101. func (w *SystemDevice) Read(bufs [][]byte, sizes []int, offset int) (count int, err error) {
  102. if w.batchDevice != nil {
  103. count, err = w.batchDevice.BatchRead(bufs, offset, sizes)
  104. } else {
  105. sizes[0], err = w.device.Read(bufs[0][offset:])
  106. if err == nil {
  107. count = 1
  108. } else if errors.Is(err, tun.ErrTooManySegments) {
  109. err = wgTun.ErrTooManySegments
  110. }
  111. }
  112. return
  113. }
  114. func (w *SystemDevice) Write(bufs [][]byte, offset int) (count int, err error) {
  115. if w.batchDevice != nil {
  116. return 0, w.batchDevice.BatchWrite(bufs, offset)
  117. } else {
  118. for _, b := range bufs {
  119. _, err = w.device.Write(b[offset:])
  120. if err != nil {
  121. return
  122. }
  123. }
  124. }
  125. // WireGuard will not read count
  126. return
  127. }
  128. func (w *SystemDevice) Flush() error {
  129. return nil
  130. }
  131. func (w *SystemDevice) MTU() (int, error) {
  132. return int(w.mtu), nil
  133. }
  134. func (w *SystemDevice) Name() (string, error) {
  135. return w.name, nil
  136. }
  137. func (w *SystemDevice) Events() <-chan wgTun.Event {
  138. return w.events
  139. }
  140. func (w *SystemDevice) Close() error {
  141. close(w.events)
  142. return w.device.Close()
  143. }
  144. func (w *SystemDevice) BatchSize() int {
  145. if w.batchDevice != nil {
  146. return w.batchDevice.BatchSize()
  147. }
  148. return 1
  149. }