device_stack.go 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  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. if !w.inet4Address.IsValid() {
  107. return nil, E.New("missing IPv4 local address")
  108. }
  109. networkProtocol = header.IPv4ProtocolNumber
  110. bind.Addr = tun.AddressFromAddr(w.inet4Address)
  111. } else {
  112. if !w.inet6Address.IsValid() {
  113. return nil, E.New("missing IPv6 local address")
  114. }
  115. networkProtocol = header.IPv6ProtocolNumber
  116. bind.Addr = tun.AddressFromAddr(w.inet6Address)
  117. }
  118. switch N.NetworkName(network) {
  119. case N.NetworkTCP:
  120. tcpConn, err := DialTCPWithBind(ctx, w.stack, bind, addr, networkProtocol)
  121. if err != nil {
  122. return nil, err
  123. }
  124. return tcpConn, nil
  125. case N.NetworkUDP:
  126. udpConn, err := gonet.DialUDP(w.stack, &bind, &addr, networkProtocol)
  127. if err != nil {
  128. return nil, err
  129. }
  130. return udpConn, nil
  131. default:
  132. return nil, E.Extend(N.ErrUnknownNetwork, network)
  133. }
  134. }
  135. func (w *stackDevice) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
  136. bind := tcpip.FullAddress{
  137. NIC: tun.DefaultNIC,
  138. }
  139. var networkProtocol tcpip.NetworkProtocolNumber
  140. if destination.IsIPv4() {
  141. networkProtocol = header.IPv4ProtocolNumber
  142. bind.Addr = tun.AddressFromAddr(w.inet4Address)
  143. } else {
  144. networkProtocol = header.IPv6ProtocolNumber
  145. bind.Addr = tun.AddressFromAddr(w.inet4Address)
  146. }
  147. udpConn, err := gonet.DialUDP(w.stack, &bind, nil, networkProtocol)
  148. if err != nil {
  149. return nil, err
  150. }
  151. return udpConn, nil
  152. }
  153. func (w *stackDevice) Inet4Address() netip.Addr {
  154. return w.inet4Address
  155. }
  156. func (w *stackDevice) Inet6Address() netip.Addr {
  157. return w.inet6Address
  158. }
  159. func (w *stackDevice) SetDevice(device *device.Device) {
  160. }
  161. func (w *stackDevice) Start() error {
  162. w.events <- wgTun.EventUp
  163. return nil
  164. }
  165. func (w *stackDevice) File() *os.File {
  166. return nil
  167. }
  168. func (w *stackDevice) Read(bufs [][]byte, sizes []int, offset int) (count int, err error) {
  169. select {
  170. case packet, ok := <-w.outbound:
  171. if !ok {
  172. return 0, os.ErrClosed
  173. }
  174. defer packet.DecRef()
  175. var copyN int
  176. /*rangeIterate(packet.Data().AsRange(), func(view *buffer.View) {
  177. copyN += copy(bufs[0][offset+copyN:], view.AsSlice())
  178. })*/
  179. for _, view := range packet.AsSlices() {
  180. copyN += copy(bufs[0][offset+copyN:], view)
  181. }
  182. sizes[0] = copyN
  183. return 1, nil
  184. case packet := <-w.packetOutbound:
  185. defer packet.Release()
  186. sizes[0] = copy(bufs[0][offset:], packet.Bytes())
  187. return 1, nil
  188. case <-w.done:
  189. return 0, os.ErrClosed
  190. }
  191. }
  192. func (w *stackDevice) Write(bufs [][]byte, offset int) (count int, err error) {
  193. for _, b := range bufs {
  194. b = b[offset:]
  195. if len(b) == 0 {
  196. continue
  197. }
  198. var networkProtocol tcpip.NetworkProtocolNumber
  199. switch header.IPVersion(b) {
  200. case header.IPv4Version:
  201. networkProtocol = header.IPv4ProtocolNumber
  202. case header.IPv6Version:
  203. networkProtocol = header.IPv6ProtocolNumber
  204. }
  205. packetBuffer := stack.NewPacketBuffer(stack.PacketBufferOptions{
  206. Payload: buffer.MakeWithData(b),
  207. })
  208. w.dispatcher.DeliverNetworkPacket(networkProtocol, packetBuffer)
  209. packetBuffer.DecRef()
  210. count++
  211. }
  212. return
  213. }
  214. func (w *stackDevice) Flush() error {
  215. return nil
  216. }
  217. func (w *stackDevice) MTU() (int, error) {
  218. return int(w.mtu), nil
  219. }
  220. func (w *stackDevice) Name() (string, error) {
  221. return "sing-box", nil
  222. }
  223. func (w *stackDevice) Events() <-chan wgTun.Event {
  224. return w.events
  225. }
  226. func (w *stackDevice) Close() error {
  227. close(w.done)
  228. close(w.events)
  229. w.stack.Close()
  230. for _, endpoint := range w.stack.CleanupEndpoints() {
  231. endpoint.Abort()
  232. }
  233. w.stack.Wait()
  234. return nil
  235. }
  236. func (w *stackDevice) BatchSize() int {
  237. return 1
  238. }
  239. func (w *stackDevice) CreateDestination(metadata adapter.InboundContext, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) {
  240. ctx := log.ContextWithNewID(w.ctx)
  241. destination, err := ping.ConnectGVisor(
  242. ctx, w.logger,
  243. metadata.Source.Addr, metadata.Destination.Addr,
  244. routeContext,
  245. w.stack,
  246. w.inet4Address, w.inet6Address,
  247. timeout,
  248. )
  249. if err != nil {
  250. return nil, err
  251. }
  252. w.logger.InfoContext(ctx, "linked ", metadata.Network, " connection from ", metadata.Source.AddrString(), " to ", metadata.Destination.AddrString())
  253. return destination, nil
  254. }
  255. var _ stack.LinkEndpoint = (*wireEndpoint)(nil)
  256. type wireEndpoint stackDevice
  257. func (ep *wireEndpoint) MTU() uint32 {
  258. return ep.mtu
  259. }
  260. func (ep *wireEndpoint) SetMTU(mtu uint32) {
  261. }
  262. func (ep *wireEndpoint) MaxHeaderLength() uint16 {
  263. return 0
  264. }
  265. func (ep *wireEndpoint) LinkAddress() tcpip.LinkAddress {
  266. return ""
  267. }
  268. func (ep *wireEndpoint) SetLinkAddress(addr tcpip.LinkAddress) {
  269. }
  270. func (ep *wireEndpoint) Capabilities() stack.LinkEndpointCapabilities {
  271. return stack.CapabilityRXChecksumOffload
  272. }
  273. func (ep *wireEndpoint) Attach(dispatcher stack.NetworkDispatcher) {
  274. ep.dispatcher = dispatcher
  275. }
  276. func (ep *wireEndpoint) IsAttached() bool {
  277. return ep.dispatcher != nil
  278. }
  279. func (ep *wireEndpoint) Wait() {
  280. }
  281. func (ep *wireEndpoint) ARPHardwareType() header.ARPHardwareType {
  282. return header.ARPHardwareNone
  283. }
  284. func (ep *wireEndpoint) AddHeader(buffer *stack.PacketBuffer) {
  285. }
  286. func (ep *wireEndpoint) ParseHeader(ptr *stack.PacketBuffer) bool {
  287. return true
  288. }
  289. func (ep *wireEndpoint) WritePackets(list stack.PacketBufferList) (int, tcpip.Error) {
  290. for _, packetBuffer := range list.AsSlice() {
  291. packetBuffer.IncRef()
  292. select {
  293. case <-ep.done:
  294. return 0, &tcpip.ErrClosedForSend{}
  295. case ep.outbound <- packetBuffer:
  296. }
  297. }
  298. return list.Len(), nil
  299. }
  300. func (ep *wireEndpoint) Close() {
  301. }
  302. func (ep *wireEndpoint) SetOnCloseAction(f func()) {
  303. }