raw_linux.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package tlsspoof
  2. import (
  3. "net"
  4. "net/netip"
  5. "github.com/sagernet/sing/common/control"
  6. E "github.com/sagernet/sing/common/exceptions"
  7. "golang.org/x/sys/unix"
  8. )
  9. const PlatformSupported = true
  10. const (
  11. // Values of enum { TCP_NO_QUEUE, TCP_RECV_QUEUE, TCP_SEND_QUEUE } from
  12. // include/net/tcp.h; not exported by golang.org/x/sys/unix.
  13. tcpRecvQueue = 1
  14. tcpSendQueue = 2
  15. )
  16. type linuxSpoofer struct {
  17. method Method
  18. src netip.AddrPort
  19. dst netip.AddrPort
  20. rawFD int
  21. rawSockAddr unix.Sockaddr
  22. sendNext uint32
  23. receiveNext uint32
  24. }
  25. func newRawSpoofer(conn net.Conn, method Method) (rawSpoofer, error) {
  26. tcpConn, src, dst, err := tcpEndpoints(conn)
  27. if err != nil {
  28. return nil, err
  29. }
  30. fd, sockaddr, err := openLinuxRawSocket(dst)
  31. if err != nil {
  32. return nil, err
  33. }
  34. spoofer := &linuxSpoofer{
  35. method: method,
  36. src: src,
  37. dst: dst,
  38. rawFD: fd,
  39. rawSockAddr: sockaddr,
  40. }
  41. err = spoofer.loadSequenceNumbers(tcpConn)
  42. if err != nil {
  43. unix.Close(fd)
  44. return nil, err
  45. }
  46. return spoofer, nil
  47. }
  48. func openLinuxRawSocket(dst netip.AddrPort) (int, unix.Sockaddr, error) {
  49. if dst.Addr().Is4() {
  50. return openIPv4RawSocket(dst)
  51. }
  52. fd, err := unix.Socket(unix.AF_INET6, unix.SOCK_RAW, unix.IPPROTO_TCP)
  53. if err != nil {
  54. return -1, nil, E.Cause(err, "open AF_INET6 SOCK_RAW")
  55. }
  56. err = unix.SetsockoptInt(fd, unix.IPPROTO_IPV6, unix.IPV6_HDRINCL, 1)
  57. if err != nil {
  58. unix.Close(fd)
  59. return -1, nil, E.Cause(err, "set IPV6_HDRINCL")
  60. }
  61. // Linux raw IPv6 sockets interpret sin6_port as a nexthdr protocol number
  62. // (see raw(7)); any value other than 0 or the socket's IPPROTO_TCP causes
  63. // sendto to fail with EINVAL. The destination is already encoded in the
  64. // user-supplied IPv6 header under IPV6_HDRINCL.
  65. sockaddr := &unix.SockaddrInet6{Addr: dst.Addr().As16()}
  66. return fd, sockaddr, nil
  67. }
  68. // loadSequenceNumbers puts the socket briefly into TCP_REPAIR mode to read
  69. // snd_nxt and rcv_nxt from the kernel. TCP_REPAIR requires CAP_NET_ADMIN;
  70. // callers must run as root or grant both CAP_NET_RAW and CAP_NET_ADMIN.
  71. //
  72. // If the TCP_REPAIR_OFF revert fails, the socket would stay in TCP_REPAIR
  73. // state and subsequent Write() calls would silently buffer instead of sending.
  74. // Surface that error so callers can abort.
  75. func (s *linuxSpoofer) loadSequenceNumbers(tcpConn *net.TCPConn) error {
  76. return control.Conn(tcpConn, func(raw uintptr) (err error) {
  77. fd := int(raw)
  78. err = unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_REPAIR, unix.TCP_REPAIR_ON)
  79. if err != nil {
  80. return E.Cause(err, "enter TCP_REPAIR (need CAP_NET_ADMIN)")
  81. }
  82. defer func() {
  83. offErr := unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_REPAIR, unix.TCP_REPAIR_OFF)
  84. if err == nil && offErr != nil {
  85. err = E.Cause(offErr, "leave TCP_REPAIR")
  86. }
  87. }()
  88. err = unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_REPAIR_QUEUE, tcpSendQueue)
  89. if err != nil {
  90. return E.Cause(err, "select TCP_SEND_QUEUE")
  91. }
  92. sendSequence, err := unix.GetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_QUEUE_SEQ)
  93. if err != nil {
  94. return E.Cause(err, "read send queue sequence")
  95. }
  96. err = unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_REPAIR_QUEUE, tcpRecvQueue)
  97. if err != nil {
  98. return E.Cause(err, "select TCP_RECV_QUEUE")
  99. }
  100. receiveSequence, err := unix.GetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_QUEUE_SEQ)
  101. if err != nil {
  102. return E.Cause(err, "read recv queue sequence")
  103. }
  104. s.sendNext = uint32(sendSequence)
  105. s.receiveNext = uint32(receiveSequence)
  106. return nil
  107. })
  108. }
  109. func (s *linuxSpoofer) Inject(payload []byte) error {
  110. frame, err := buildSpoofFrame(s.method, s.src, s.dst, s.sendNext, s.receiveNext, payload)
  111. if err != nil {
  112. return err
  113. }
  114. err = unix.Sendto(s.rawFD, frame, 0, s.rawSockAddr)
  115. if err != nil {
  116. return E.Cause(err, "sendto raw socket")
  117. }
  118. return nil
  119. }
  120. func (s *linuxSpoofer) Close() error {
  121. if s.rawFD < 0 {
  122. return nil
  123. }
  124. err := unix.Close(s.rawFD)
  125. s.rawFD = -1
  126. return err
  127. }