device_stack.go 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. //go:build with_gvisor
  2. package wireguard
  3. import (
  4. "context"
  5. "net"
  6. "net/netip"
  7. "os"
  8. "time"
  9. "github.com/sagernet/gvisor/pkg/buffer"
  10. "github.com/sagernet/gvisor/pkg/tcpip"
  11. "github.com/sagernet/gvisor/pkg/tcpip/adapters/gonet"
  12. "github.com/sagernet/gvisor/pkg/tcpip/header"
  13. "github.com/sagernet/gvisor/pkg/tcpip/network/ipv4"
  14. "github.com/sagernet/gvisor/pkg/tcpip/network/ipv6"
  15. "github.com/sagernet/gvisor/pkg/tcpip/stack"
  16. "github.com/sagernet/gvisor/pkg/tcpip/transport/icmp"
  17. "github.com/sagernet/gvisor/pkg/tcpip/transport/tcp"
  18. "github.com/sagernet/gvisor/pkg/tcpip/transport/udp"
  19. "github.com/sagernet/sing-box/adapter"
  20. "github.com/sagernet/sing-box/log"
  21. "github.com/sagernet/sing-tun"
  22. "github.com/sagernet/sing-tun/ping"
  23. "github.com/sagernet/sing/common/buf"
  24. E "github.com/sagernet/sing/common/exceptions"
  25. M "github.com/sagernet/sing/common/metadata"
  26. N "github.com/sagernet/sing/common/network"
  27. "github.com/sagernet/wireguard-go/device"
  28. wgTun "github.com/sagernet/wireguard-go/tun"
  29. )
  30. var _ NatDevice = (*stackDevice)(nil)
  31. type stackDevice struct {
  32. ctx context.Context
  33. logger log.ContextLogger
  34. stack *stack.Stack
  35. mtu uint32
  36. events chan wgTun.Event
  37. outbound chan *stack.PacketBuffer
  38. packetOutbound chan *buf.Buffer
  39. done chan struct{}
  40. dispatcher stack.NetworkDispatcher
  41. inet4Address netip.Addr
  42. inet6Address netip.Addr
  43. }
  44. func newStackDevice(options DeviceOptions) (*stackDevice, error) {
  45. tunDevice := &stackDevice{
  46. ctx: options.Context,
  47. logger: options.Logger,
  48. mtu: options.MTU,
  49. events: make(chan wgTun.Event, 1),
  50. outbound: make(chan *stack.PacketBuffer, 256),
  51. packetOutbound: make(chan *buf.Buffer, 256),
  52. done: make(chan struct{}),
  53. }
  54. ipStack, err := tun.NewGVisorStackWithOptions((*wireEndpoint)(tunDevice), stack.NICOptions{}, true)
  55. if err != nil {
  56. return nil, err
  57. }
  58. var (
  59. inet4Address netip.Addr
  60. inet6Address netip.Addr
  61. )
  62. for _, prefix := range options.Address {
  63. addr := tun.AddressFromAddr(prefix.Addr())
  64. protoAddr := tcpip.ProtocolAddress{
  65. AddressWithPrefix: tcpip.AddressWithPrefix{
  66. Address: addr,
  67. PrefixLen: prefix.Bits(),
  68. },
  69. }
  70. if prefix.Addr().Is4() {
  71. inet4Address = prefix.Addr()
  72. tunDevice.inet4Address = inet4Address
  73. protoAddr.Protocol = ipv4.ProtocolNumber
  74. } else {
  75. inet6Address = prefix.Addr()
  76. tunDevice.inet6Address = inet6Address
  77. protoAddr.Protocol = ipv6.ProtocolNumber
  78. }
  79. gErr := ipStack.AddProtocolAddress(tun.DefaultNIC, protoAddr, stack.AddressProperties{})
  80. if gErr != nil {
  81. return nil, E.New("parse local address ", protoAddr.AddressWithPrefix, ": ", gErr.String())
  82. }
  83. }
  84. tunDevice.stack = ipStack
  85. if options.Handler != nil {
  86. ipStack.SetTransportProtocolHandler(tcp.ProtocolNumber, tun.NewTCPForwarder(options.Context, ipStack, options.Handler).HandlePacket)
  87. ipStack.SetTransportProtocolHandler(udp.ProtocolNumber, tun.NewUDPForwarder(options.Context, ipStack, options.Handler, options.UDPTimeout).HandlePacket)
  88. icmpForwarder := tun.NewICMPForwarder(options.Context, ipStack, options.Handler, options.UDPTimeout)
  89. icmpForwarder.SetLocalAddresses(inet4Address, inet6Address)
  90. ipStack.SetTransportProtocolHandler(icmp.ProtocolNumber4, icmpForwarder.HandlePacket)
  91. ipStack.SetTransportProtocolHandler(icmp.ProtocolNumber6, icmpForwarder.HandlePacket)
  92. }
  93. return tunDevice, nil
  94. }
  95. func (w *stackDevice) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
  96. addr := tcpip.FullAddress{
  97. NIC: tun.DefaultNIC,
  98. Port: destination.Port,
  99. Addr: tun.AddressFromAddr(destination.Addr),
  100. }
  101. bind := tcpip.FullAddress{
  102. NIC: tun.DefaultNIC,
  103. }
  104. var networkProtocol tcpip.NetworkProtocolNumber
  105. if destination.IsIPv4() {
  106. networkProtocol = header.IPv4ProtocolNumber
  107. bind.Addr = tun.AddressFromAddr(w.inet4Address)
  108. } else {
  109. networkProtocol = header.IPv6ProtocolNumber
  110. bind.Addr = tun.AddressFromAddr(w.inet4Address)
  111. }
  112. switch N.NetworkName(network) {
  113. case N.NetworkTCP:
  114. tcpConn, err := DialTCPWithBind(ctx, w.stack, bind, addr, networkProtocol)
  115. if err != nil {
  116. return nil, err
  117. }
  118. return tcpConn, nil
  119. case N.NetworkUDP:
  120. udpConn, err := gonet.DialUDP(w.stack, &bind, &addr, networkProtocol)
  121. if err != nil {
  122. return nil, err
  123. }
  124. return udpConn, nil
  125. default:
  126. return nil, E.Extend(N.ErrUnknownNetwork, network)
  127. }
  128. }
  129. func (w *stackDevice) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
  130. bind := tcpip.FullAddress{
  131. NIC: tun.DefaultNIC,
  132. }
  133. var networkProtocol tcpip.NetworkProtocolNumber
  134. if destination.IsIPv4() {
  135. networkProtocol = header.IPv4ProtocolNumber
  136. bind.Addr = tun.AddressFromAddr(w.inet4Address)
  137. } else {
  138. networkProtocol = header.IPv6ProtocolNumber
  139. bind.Addr = tun.AddressFromAddr(w.inet4Address)
  140. }
  141. udpConn, err := gonet.DialUDP(w.stack, &bind, nil, networkProtocol)
  142. if err != nil {
  143. return nil, err
  144. }
  145. return udpConn, nil
  146. }
  147. func (w *stackDevice) Inet4Address() netip.Addr {
  148. return w.inet4Address
  149. }
  150. func (w *stackDevice) Inet6Address() netip.Addr {
  151. return w.inet6Address
  152. }
  153. func (w *stackDevice) SetDevice(device *device.Device) {
  154. }
  155. func (w *stackDevice) Start() error {
  156. w.events <- wgTun.EventUp
  157. return nil
  158. }
  159. func (w *stackDevice) File() *os.File {
  160. return nil
  161. }
  162. func (w *stackDevice) Read(bufs [][]byte, sizes []int, offset int) (count int, err error) {
  163. select {
  164. case packet, ok := <-w.outbound:
  165. if !ok {
  166. return 0, os.ErrClosed
  167. }
  168. defer packet.DecRef()
  169. var copyN int
  170. /*rangeIterate(packet.Data().AsRange(), func(view *buffer.View) {
  171. copyN += copy(bufs[0][offset+copyN:], view.AsSlice())
  172. })*/
  173. for _, view := range packet.AsSlices() {
  174. copyN += copy(bufs[0][offset+copyN:], view)
  175. }
  176. sizes[0] = copyN
  177. return 1, nil
  178. case packet := <-w.packetOutbound:
  179. defer packet.Release()
  180. sizes[0] = copy(bufs[0][offset:], packet.Bytes())
  181. return 1, nil
  182. case <-w.done:
  183. return 0, os.ErrClosed
  184. }
  185. }
  186. func (w *stackDevice) Write(bufs [][]byte, offset int) (count int, err error) {
  187. for _, b := range bufs {
  188. b = b[offset:]
  189. if len(b) == 0 {
  190. continue
  191. }
  192. var networkProtocol tcpip.NetworkProtocolNumber
  193. switch header.IPVersion(b) {
  194. case header.IPv4Version:
  195. networkProtocol = header.IPv4ProtocolNumber
  196. case header.IPv6Version:
  197. networkProtocol = header.IPv6ProtocolNumber
  198. }
  199. packetBuffer := stack.NewPacketBuffer(stack.PacketBufferOptions{
  200. Payload: buffer.MakeWithData(b),
  201. })
  202. w.dispatcher.DeliverNetworkPacket(networkProtocol, packetBuffer)
  203. packetBuffer.DecRef()
  204. count++
  205. }
  206. return
  207. }
  208. func (w *stackDevice) Flush() error {
  209. return nil
  210. }
  211. func (w *stackDevice) MTU() (int, error) {
  212. return int(w.mtu), nil
  213. }
  214. func (w *stackDevice) Name() (string, error) {
  215. return "sing-box", nil
  216. }
  217. func (w *stackDevice) Events() <-chan wgTun.Event {
  218. return w.events
  219. }
  220. func (w *stackDevice) Close() error {
  221. close(w.done)
  222. close(w.events)
  223. w.stack.Close()
  224. for _, endpoint := range w.stack.CleanupEndpoints() {
  225. endpoint.Abort()
  226. }
  227. w.stack.Wait()
  228. return nil
  229. }
  230. func (w *stackDevice) BatchSize() int {
  231. return 1
  232. }
  233. func (w *stackDevice) CreateDestination(metadata adapter.InboundContext, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) {
  234. ctx := log.ContextWithNewID(w.ctx)
  235. destination, err := ping.ConnectGVisor(
  236. ctx, w.logger,
  237. metadata.Source.Addr, metadata.Destination.Addr,
  238. routeContext,
  239. w.stack,
  240. w.inet4Address, w.inet6Address,
  241. timeout,
  242. )
  243. if err != nil {
  244. return nil, err
  245. }
  246. w.logger.InfoContext(ctx, "linked ", metadata.Network, " connection from ", metadata.Source.AddrString(), " to ", metadata.Destination.AddrString())
  247. return destination, nil
  248. }
  249. var _ stack.LinkEndpoint = (*wireEndpoint)(nil)
  250. type wireEndpoint stackDevice
  251. func (ep *wireEndpoint) MTU() uint32 {
  252. return ep.mtu
  253. }
  254. func (ep *wireEndpoint) SetMTU(mtu uint32) {
  255. }
  256. func (ep *wireEndpoint) MaxHeaderLength() uint16 {
  257. return 0
  258. }
  259. func (ep *wireEndpoint) LinkAddress() tcpip.LinkAddress {
  260. return ""
  261. }
  262. func (ep *wireEndpoint) SetLinkAddress(addr tcpip.LinkAddress) {
  263. }
  264. func (ep *wireEndpoint) Capabilities() stack.LinkEndpointCapabilities {
  265. return stack.CapabilityRXChecksumOffload
  266. }
  267. func (ep *wireEndpoint) Attach(dispatcher stack.NetworkDispatcher) {
  268. ep.dispatcher = dispatcher
  269. }
  270. func (ep *wireEndpoint) IsAttached() bool {
  271. return ep.dispatcher != nil
  272. }
  273. func (ep *wireEndpoint) Wait() {
  274. }
  275. func (ep *wireEndpoint) ARPHardwareType() header.ARPHardwareType {
  276. return header.ARPHardwareNone
  277. }
  278. func (ep *wireEndpoint) AddHeader(buffer *stack.PacketBuffer) {
  279. }
  280. func (ep *wireEndpoint) ParseHeader(ptr *stack.PacketBuffer) bool {
  281. return true
  282. }
  283. func (ep *wireEndpoint) WritePackets(list stack.PacketBufferList) (int, tcpip.Error) {
  284. for _, packetBuffer := range list.AsSlice() {
  285. packetBuffer.IncRef()
  286. select {
  287. case <-ep.done:
  288. return 0, &tcpip.ErrClosedForSend{}
  289. case ep.outbound <- packetBuffer:
  290. }
  291. }
  292. return list.Len(), nil
  293. }
  294. func (ep *wireEndpoint) Close() {
  295. }
  296. func (ep *wireEndpoint) SetOnCloseAction(f func()) {
  297. }