gvisor_posix.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package tun
  2. import (
  3. "os"
  4. "github.com/sagernet/sing/common"
  5. "github.com/sagernet/sing/common/buf"
  6. "github.com/sagernet/sing/common/rw"
  7. gBuffer "gvisor.dev/gvisor/pkg/buffer"
  8. "gvisor.dev/gvisor/pkg/tcpip"
  9. "gvisor.dev/gvisor/pkg/tcpip/header"
  10. "gvisor.dev/gvisor/pkg/tcpip/stack"
  11. )
  12. var _ stack.LinkEndpoint = (*PosixEndpoint)(nil)
  13. type PosixEndpoint struct {
  14. fd uintptr
  15. mtu uint32
  16. file *os.File
  17. dispatcher stack.NetworkDispatcher
  18. }
  19. func NewPosixEndpoint(tunFd uintptr, tunMtu uint32) (stack.LinkEndpoint, error) {
  20. return &PosixEndpoint{
  21. fd: tunFd,
  22. mtu: tunMtu,
  23. file: os.NewFile(tunFd, "tun"),
  24. }, nil
  25. }
  26. func (e *PosixEndpoint) MTU() uint32 {
  27. return e.mtu
  28. }
  29. func (e *PosixEndpoint) MaxHeaderLength() uint16 {
  30. return 0
  31. }
  32. func (e *PosixEndpoint) LinkAddress() tcpip.LinkAddress {
  33. return ""
  34. }
  35. func (e *PosixEndpoint) Capabilities() stack.LinkEndpointCapabilities {
  36. return stack.CapabilityNone
  37. }
  38. func (e *PosixEndpoint) Attach(dispatcher stack.NetworkDispatcher) {
  39. if dispatcher == nil && e.dispatcher != nil {
  40. e.dispatcher = nil
  41. return
  42. }
  43. if dispatcher != nil && e.dispatcher == nil {
  44. e.dispatcher = dispatcher
  45. go e.dispatchLoop()
  46. }
  47. }
  48. func (e *PosixEndpoint) dispatchLoop() {
  49. _buffer := buf.StackNewPacket()
  50. defer common.KeepAlive(_buffer)
  51. buffer := common.Dup(_buffer)
  52. defer buffer.Release()
  53. for {
  54. n, err := e.file.Read(buffer.FreeBytes())
  55. if err != nil {
  56. break
  57. }
  58. var view gBuffer.View
  59. view.Append(buffer.To(n))
  60. pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
  61. Payload: view,
  62. IsForwardedPacket: true,
  63. })
  64. defer pkt.DecRef()
  65. var p tcpip.NetworkProtocolNumber
  66. ipHeader, ok := pkt.Data().PullUp(1)
  67. if !ok {
  68. continue
  69. }
  70. switch header.IPVersion(ipHeader) {
  71. case header.IPv4Version:
  72. p = header.IPv4ProtocolNumber
  73. case header.IPv6Version:
  74. p = header.IPv6ProtocolNumber
  75. default:
  76. continue
  77. }
  78. e.dispatcher.DeliverNetworkPacket(p, pkt)
  79. }
  80. }
  81. func (e *PosixEndpoint) IsAttached() bool {
  82. return e.dispatcher != nil
  83. }
  84. func (e *PosixEndpoint) Wait() {
  85. }
  86. func (e *PosixEndpoint) ARPHardwareType() header.ARPHardwareType {
  87. return header.ARPHardwareNone
  88. }
  89. func (e *PosixEndpoint) AddHeader(buffer *stack.PacketBuffer) {
  90. }
  91. func (e *PosixEndpoint) WritePackets(pkts stack.PacketBufferList) (int, tcpip.Error) {
  92. var n int
  93. for _, packet := range pkts.AsSlice() {
  94. _, err := rw.WriteV(e.fd, packet.Slices())
  95. if err != nil {
  96. return n, &tcpip.ErrAborted{}
  97. }
  98. n++
  99. }
  100. return n, nil
  101. }