gvisor.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package tun
  2. import (
  3. "context"
  4. "github.com/sagernet/sing-box/adapter"
  5. "github.com/sagernet/sing-box/log"
  6. "github.com/sagernet/sing/common"
  7. "github.com/sagernet/sing/common/bufio"
  8. E "github.com/sagernet/sing/common/exceptions"
  9. M "github.com/sagernet/sing/common/metadata"
  10. "gvisor.dev/gvisor/pkg/tcpip"
  11. "gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
  12. "gvisor.dev/gvisor/pkg/tcpip/header"
  13. "gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
  14. "gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
  15. "gvisor.dev/gvisor/pkg/tcpip/stack"
  16. "gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
  17. "gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
  18. "gvisor.dev/gvisor/pkg/tcpip/transport/udp"
  19. "gvisor.dev/gvisor/pkg/waiter"
  20. )
  21. const defaultNIC tcpip.NICID = 1
  22. var _ adapter.Service = (*GVisorTun)(nil)
  23. type GVisorTun struct {
  24. ctx context.Context
  25. tunFd uintptr
  26. tunMtu uint32
  27. handler Handler
  28. stack *stack.Stack
  29. }
  30. func NewGVisor(ctx context.Context, tunFd uintptr, tunMtu uint32, handler Handler) *GVisorTun {
  31. return &GVisorTun{
  32. ctx: ctx,
  33. tunFd: tunFd,
  34. tunMtu: tunMtu,
  35. handler: handler,
  36. }
  37. }
  38. func (t *GVisorTun) Start() error {
  39. linkEndpoint, err := NewEndpoint(t.tunFd, t.tunMtu)
  40. if err != nil {
  41. return err
  42. }
  43. ipStack := stack.New(stack.Options{
  44. NetworkProtocols: []stack.NetworkProtocolFactory{
  45. ipv4.NewProtocol,
  46. ipv6.NewProtocol,
  47. },
  48. TransportProtocols: []stack.TransportProtocolFactory{
  49. tcp.NewProtocol,
  50. udp.NewProtocol,
  51. icmp.NewProtocol4,
  52. icmp.NewProtocol6,
  53. },
  54. })
  55. tErr := ipStack.CreateNIC(defaultNIC, linkEndpoint)
  56. if tErr != nil {
  57. return E.New("create nic: ", tErr)
  58. }
  59. ipStack.SetRouteTable([]tcpip.Route{
  60. {Destination: header.IPv4EmptySubnet, NIC: defaultNIC},
  61. {Destination: header.IPv6EmptySubnet, NIC: defaultNIC},
  62. })
  63. ipStack.SetSpoofing(defaultNIC, true)
  64. ipStack.SetPromiscuousMode(defaultNIC, true)
  65. bufSize := 20 * 1024
  66. ipStack.SetTransportProtocolOption(tcp.ProtocolNumber, &tcpip.TCPReceiveBufferSizeRangeOption{
  67. Min: 1,
  68. Default: bufSize,
  69. Max: bufSize,
  70. })
  71. ipStack.SetTransportProtocolOption(tcp.ProtocolNumber, &tcpip.TCPSendBufferSizeRangeOption{
  72. Min: 1,
  73. Default: bufSize,
  74. Max: bufSize,
  75. })
  76. sOpt := tcpip.TCPSACKEnabled(true)
  77. ipStack.SetTransportProtocolOption(tcp.ProtocolNumber, &sOpt)
  78. mOpt := tcpip.TCPModerateReceiveBufferOption(true)
  79. ipStack.SetTransportProtocolOption(tcp.ProtocolNumber, &mOpt)
  80. tcpForwarder := tcp.NewForwarder(ipStack, 0, 1024, func(r *tcp.ForwarderRequest) {
  81. var wq waiter.Queue
  82. endpoint, err := r.CreateEndpoint(&wq)
  83. if err != nil {
  84. r.Complete(true)
  85. return
  86. }
  87. r.Complete(false)
  88. endpoint.SocketOptions().SetKeepAlive(true)
  89. tcpConn := gonet.NewTCPConn(&wq, endpoint)
  90. lAddr := tcpConn.RemoteAddr()
  91. rAddr := tcpConn.LocalAddr()
  92. if lAddr == nil || rAddr == nil {
  93. tcpConn.Close()
  94. return
  95. }
  96. go func() {
  97. var metadata M.Metadata
  98. metadata.Source = M.SocksaddrFromNet(lAddr)
  99. metadata.Destination = M.SocksaddrFromNet(rAddr)
  100. ctx := log.ContextWithID(t.ctx)
  101. hErr := t.handler.NewConnection(ctx, tcpConn, metadata)
  102. if hErr != nil {
  103. t.handler.NewError(ctx, hErr)
  104. }
  105. }()
  106. })
  107. ipStack.SetTransportProtocolHandler(tcp.ProtocolNumber, func(id stack.TransportEndpointID, buffer *stack.PacketBuffer) bool {
  108. return tcpForwarder.HandlePacket(id, buffer)
  109. })
  110. udpForwarder := udp.NewForwarder(ipStack, func(request *udp.ForwarderRequest) {
  111. var wq waiter.Queue
  112. endpoint, err := request.CreateEndpoint(&wq)
  113. if err != nil {
  114. return
  115. }
  116. udpConn := gonet.NewUDPConn(ipStack, &wq, endpoint)
  117. lAddr := udpConn.RemoteAddr()
  118. rAddr := udpConn.LocalAddr()
  119. if lAddr == nil || rAddr == nil {
  120. udpConn.Close()
  121. return
  122. }
  123. go func() {
  124. var metadata M.Metadata
  125. metadata.Source = M.SocksaddrFromNet(lAddr)
  126. metadata.Destination = M.SocksaddrFromNet(rAddr)
  127. ctx := log.ContextWithID(t.ctx)
  128. hErr := t.handler.NewPacketConnection(ctx, bufio.NewPacketConn(&bufio.UnbindPacketConn{ExtendedConn: bufio.NewExtendedConn(udpConn), Addr: M.SocksaddrFromNet(rAddr)}), metadata)
  129. if hErr != nil {
  130. t.handler.NewError(ctx, hErr)
  131. }
  132. }()
  133. })
  134. ipStack.SetTransportProtocolHandler(udp.ProtocolNumber, udpForwarder.HandlePacket)
  135. t.stack = ipStack
  136. return nil
  137. }
  138. func (t *GVisorTun) Close() error {
  139. return common.Close(
  140. common.PtrOrNil(t.stack),
  141. )
  142. }