secure_io.go 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. package aerotun
  2. import (
  3. "encoding/binary"
  4. "errors"
  5. "fmt"
  6. "net"
  7. "net/netip"
  8. "sync/atomic"
  9. "syscall"
  10. "time"
  11. "github.com/pierrec/lz4/v4"
  12. "golang.org/x/net/ipv4"
  13. "golang.org/x/net/ipv6"
  14. )
  15. const secureBatchSize = 16
  16. type batchSocket interface {
  17. ReadBatch([]ipv4.Message, int) (int, error)
  18. WriteBatch([]ipv4.Message, int) (int, error)
  19. }
  20. func newBatchSocket(c *net.UDPConn) batchSocket {
  21. if c.LocalAddr().(*net.UDPAddr).IP.To4() != nil {
  22. return ipv4.NewPacketConn(c)
  23. }
  24. return ipv6.NewPacketConn(c)
  25. }
  26. type securePacket struct {
  27. buf []byte
  28. n, wire int
  29. compressed bool
  30. }
  31. func (t *TunnelRunner) txLoopSecure() {
  32. size := t.cfg.MTU + secureHeaderSize + 16
  33. pool := make(chan *securePacket, secureBatchSize*2)
  34. queue := make(chan *securePacket, secureBatchSize)
  35. for range cap(pool) {
  36. pool <- &securePacket{buf: make([]byte, size)}
  37. }
  38. done := make(chan struct{})
  39. go func() {
  40. defer close(done)
  41. defer close(queue)
  42. for {
  43. var p *securePacket
  44. select {
  45. case <-t.stopChan:
  46. return
  47. case p = <-pool:
  48. }
  49. n, err := t.dev.Read(p.buf[secureHeaderSize : secureHeaderSize+t.cfg.MTU])
  50. if err != nil {
  51. select {
  52. case <-t.stopChan:
  53. return
  54. default:
  55. }
  56. t.setError(fmt.Errorf("secure interface read: %w", err))
  57. pool <- p
  58. time.Sleep(10 * time.Millisecond)
  59. continue
  60. }
  61. if n == 0 || n > int(t.effectiveMTU.Load()) || !validIPPacket(p.buf[secureHeaderSize:secureHeaderSize+n]) {
  62. t.recordDrop(&t.dropInvalidOutgoing, 1)
  63. pool <- p
  64. continue
  65. }
  66. p.n = n
  67. select {
  68. case <-t.stopChan:
  69. return
  70. case queue <- p:
  71. }
  72. }
  73. }()
  74. defer func() { <-done }()
  75. conn := newBatchSocket(t.udpConn)
  76. messages := make([]ipv4.Message, secureBatchSize)
  77. var buffers [secureBatchSize][1][]byte
  78. for i := range messages {
  79. messages[i].Buffers = buffers[i][:]
  80. }
  81. var packets [secureBatchSize]*securePacket
  82. var nonce [24]byte
  83. var comp []byte
  84. if t.cfg.Compression {
  85. comp = make([]byte, lz4.CompressBlockBound(t.cfg.MTU))
  86. }
  87. for {
  88. var first *securePacket
  89. select {
  90. case <-t.stopChan:
  91. return
  92. case p, ok := <-queue:
  93. if !ok {
  94. return
  95. }
  96. first = p
  97. }
  98. count := 1
  99. packets[0] = first
  100. drain:
  101. for count < secureBatchSize {
  102. select {
  103. case p, ok := <-queue:
  104. if !ok {
  105. break drain
  106. }
  107. packets[count] = p
  108. count++
  109. default:
  110. break drain
  111. }
  112. }
  113. target := t.target()
  114. ready := 0
  115. for i := 0; i < count; i++ {
  116. p := packets[i]
  117. payload := p.buf[secureHeaderSize : secureHeaderSize+p.n]
  118. flags := byte(0)
  119. p.compressed = false
  120. p.wire = p.n
  121. if target != nil && t.secure.compressionEnabled() && len(comp) > 0 && p.n > 40 {
  122. if n, err := lz4.CompressBlock(payload, comp, nil); err == nil && n > 0 && n < p.n-16 {
  123. payload = comp[:n]
  124. flags = FlagCompressedLZ4
  125. p.compressed = true
  126. p.wire = n
  127. }
  128. }
  129. if target == nil {
  130. t.recordDrop(&t.dropMissingSession, 1)
  131. pool <- p
  132. continue
  133. }
  134. out, err := t.secure.sealInto(p.buf[:0], &nonce, flags, payload)
  135. if err != nil {
  136. t.recordDrop(&t.dropMissingSession, 1)
  137. pool <- p
  138. continue
  139. }
  140. packets[ready] = p
  141. messages[ready].Buffers[0] = out
  142. messages[ready].Addr = target
  143. ready++
  144. }
  145. sent := 0
  146. for sent < ready {
  147. n, err := conn.WriteBatch(messages[sent:ready], 0)
  148. var payloadBytes, wireBytes, savedBytes, compressed, raw uint64
  149. for j := sent; j < sent+n; j++ {
  150. p := packets[j]
  151. payloadBytes += uint64(p.n)
  152. wireBytes += uint64(len(messages[j].Buffers[0]))
  153. if p.compressed {
  154. compressed++
  155. savedBytes += uint64(p.n - p.wire)
  156. } else {
  157. raw++
  158. }
  159. }
  160. if n > 0 {
  161. atomic.AddUint64(&t.txBytes, payloadBytes)
  162. atomic.AddUint64(&t.rawBytesOut, payloadBytes)
  163. atomic.AddUint64(&t.packetsTx, uint64(n))
  164. atomic.AddUint64(&t.wireBytesOut, wireBytes)
  165. atomic.AddUint64(&t.compressedPackets, compressed)
  166. atomic.AddUint64(&t.savedBytes, savedBytes)
  167. atomic.AddUint64(&t.rawPackets, raw)
  168. }
  169. sent += n
  170. if err != nil || n == 0 {
  171. if err != nil {
  172. t.setError(err)
  173. }
  174. t.recordDrop(&t.dropSendFailure, uint64(ready-sent))
  175. break
  176. }
  177. }
  178. for i := 0; i < ready; i++ {
  179. pool <- packets[i]
  180. }
  181. }
  182. }
  183. func (t *TunnelRunner) allowedSource(b []byte) bool {
  184. var src netip.Addr
  185. if b[0]>>4 == 4 {
  186. var ip [4]byte
  187. copy(ip[:], b[12:16])
  188. src = netip.AddrFrom4(ip)
  189. } else {
  190. var ip [16]byte
  191. copy(ip[:], b[8:24])
  192. src = netip.AddrFrom16(ip)
  193. }
  194. for _, prefix := range t.allowed {
  195. if prefix.Contains(src) {
  196. return true
  197. }
  198. }
  199. return false
  200. }
  201. func (t *TunnelRunner) rxLoopSecure() {
  202. conn := newBatchSocket(t.udpConn)
  203. size := max(t.cfg.MTU+secureHeaderSize+16, handshakeMaxSize)
  204. messages := make([]ipv4.Message, secureBatchSize)
  205. buffers := make([][]byte, secureBatchSize)
  206. var vectors [secureBatchSize][1][]byte
  207. for i := range messages {
  208. buffers[i] = make([]byte, size)
  209. vectors[i][0] = buffers[i]
  210. messages[i].Buffers = vectors[i][:]
  211. }
  212. plain := make([]byte, t.cfg.MTU)
  213. var decomp []byte
  214. if t.cfg.Compression {
  215. decomp = make([]byte, t.cfg.MTU)
  216. }
  217. var nonce [24]byte
  218. for {
  219. n, err := conn.ReadBatch(messages, 0)
  220. if err != nil {
  221. select {
  222. case <-t.stopChan:
  223. return
  224. default:
  225. }
  226. t.setError(err)
  227. continue
  228. }
  229. for i := 0; i < n; i++ {
  230. m := &messages[i]
  231. src, ok := m.Addr.(*net.UDPAddr)
  232. if !ok || m.Flags&syscall.MSG_TRUNC != 0 || m.N < secureHeaderSize+16 {
  233. t.recordDrop(&t.dropInvalidIncoming, 1)
  234. continue
  235. }
  236. if t.cfg.Mode == "client" && !udpAddrsEqual(t.target(), src) {
  237. continue
  238. }
  239. b := m.Buffers[0][:m.N]
  240. if b[2] != 3 {
  241. atomic.AddUint64(&t.authFailures, 1)
  242. continue
  243. }
  244. if b[3] == secureInit || b[3] == secureResponse || b[3] == secureCookie {
  245. response, peerMTU, err := t.secure.handleHandshake(b, int(t.effectiveMTU.Load()), src.AddrPort())
  246. if err != nil {
  247. if !errors.Is(err, errHandshakeRate) {
  248. atomic.AddUint64(&t.authFailures, 1)
  249. }
  250. continue
  251. }
  252. atomic.AddUint64(&t.wireBytesIn, uint64(m.N))
  253. if response != nil {
  254. if n, err := t.udpConn.WriteToUDP(response, src); err == nil {
  255. atomic.AddUint64(&t.wireBytesOut, uint64(n))
  256. } else {
  257. t.setError(err)
  258. }
  259. }
  260. if peerMTU > 0 {
  261. if err := t.adjustMTU(src.IP, peerMTU); err != nil {
  262. t.setError(err)
  263. continue
  264. }
  265. t.markSecurePeer(src)
  266. if err := t.sendControl(FlagKeepalive, src, zeroSession); err != nil {
  267. t.setError(err)
  268. }
  269. }
  270. continue
  271. }
  272. payload, flags, peerMTU, err := t.secure.openInto(plain, &nonce, b)
  273. if err != nil {
  274. if errors.Is(err, errReplay) {
  275. atomic.AddUint64(&t.replayDrops, 1)
  276. } else {
  277. atomic.AddUint64(&t.authFailures, 1)
  278. }
  279. continue
  280. }
  281. atomic.AddUint64(&t.wireBytesIn, uint64(m.N))
  282. oldMTU := t.effectiveMTU.Load()
  283. if flags == FlagKeepalive {
  284. peerMTU = int(binary.BigEndian.Uint16(payload))
  285. }
  286. if peerMTU > 0 {
  287. if err := t.adjustMTU(src.IP, peerMTU); err != nil {
  288. t.setError(err)
  289. continue
  290. }
  291. }
  292. t.markSecurePeer(src)
  293. if flags == FlagKeepalive {
  294. if t.effectiveMTU.Load() < oldMTU {
  295. if err := t.sendControl(FlagKeepalive, src, zeroSession); err != nil {
  296. t.setError(err)
  297. }
  298. }
  299. continue
  300. }
  301. if flags == FlagCompressedLZ4 {
  302. if len(decomp) == 0 {
  303. t.recordDrop(&t.dropInvalidIncoming, 1)
  304. continue
  305. }
  306. size, err := lz4.UncompressBlock(payload, decomp[:int(t.effectiveMTU.Load())])
  307. if err != nil || size == 0 {
  308. t.recordDrop(&t.dropInvalidIncoming, 1)
  309. continue
  310. }
  311. payload = decomp[:size]
  312. }
  313. if len(payload) > int(t.effectiveMTU.Load()) || !validIPPacket(payload) {
  314. t.recordDrop(&t.dropInvalidIncoming, 1)
  315. continue
  316. }
  317. if !t.allowedSource(payload) {
  318. t.recordDrop(&t.dropSourcePolicy, 1)
  319. continue
  320. }
  321. wrote, err := t.dev.Write(payload)
  322. if err != nil || wrote != len(payload) {
  323. t.recordDrop(&t.dropInterfaceWrite, 1)
  324. if err != nil {
  325. t.setError(err)
  326. }
  327. continue
  328. }
  329. atomic.AddUint64(&t.rxBytes, uint64(wrote))
  330. atomic.AddUint64(&t.rawBytesIn, uint64(wrote))
  331. atomic.AddUint64(&t.packetsRx, 1)
  332. }
  333. }
  334. }
  335. func (t *TunnelRunner) markSecurePeer(src *net.UDPAddr) {
  336. t.mu.Lock()
  337. if !udpAddrsEqual(t.remoteAddr, src) {
  338. t.remoteAddr = src
  339. }
  340. t.lastHandshake = time.Now()
  341. t.mu.Unlock()
  342. }
  343. func (t *TunnelRunner) keepaliveSecure() {
  344. ticker := time.NewTicker(time.Second)
  345. defer ticker.Stop()
  346. lastSent := time.Time{}
  347. for {
  348. t.secure.expire()
  349. target := t.target()
  350. t.mu.RLock()
  351. connected := !t.lastHandshake.IsZero() && time.Since(t.lastHandshake) < peerTimeout
  352. t.mu.RUnlock()
  353. if target != nil {
  354. b, err := t.secure.initiation(int(t.effectiveMTU.Load()), !connected)
  355. if err != nil {
  356. t.setError(err)
  357. } else if b != nil {
  358. if n, err := t.udpConn.WriteToUDP(b, target); err == nil {
  359. atomic.AddUint64(&t.wireBytesOut, uint64(n))
  360. } else {
  361. t.setError(err)
  362. }
  363. }
  364. if connected && time.Since(lastSent) >= 20*time.Second {
  365. if err := t.sendControl(FlagKeepalive, target, zeroSession); err != nil {
  366. t.setError(err)
  367. }
  368. lastSent = time.Now()
  369. }
  370. }
  371. select {
  372. case <-t.stopChan:
  373. return
  374. case <-ticker.C:
  375. }
  376. }
  377. }