interface.go 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064
  1. package nebula
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "net/netip"
  8. "os"
  9. "runtime"
  10. "sync/atomic"
  11. "time"
  12. "github.com/gaissmai/bart"
  13. "github.com/rcrowley/go-metrics"
  14. "github.com/sirupsen/logrus"
  15. "github.com/slackhq/nebula/config"
  16. "github.com/slackhq/nebula/firewall"
  17. "github.com/slackhq/nebula/header"
  18. "github.com/slackhq/nebula/overlay"
  19. "github.com/slackhq/nebula/udp"
  20. )
  21. const (
  22. mtu = 9001
  23. defaultGSOFlushInterval = 150 * time.Microsecond
  24. defaultBatchQueueDepthFactor = 4
  25. defaultGSOMaxSegments = 8
  26. maxKernelGSOSegments = 64
  27. )
  28. type InterfaceConfig struct {
  29. HostMap *HostMap
  30. Outside udp.Conn
  31. Inside overlay.Device
  32. pki *PKI
  33. Cipher string
  34. Firewall *Firewall
  35. ServeDns bool
  36. HandshakeManager *HandshakeManager
  37. lightHouse *LightHouse
  38. connectionManager *connectionManager
  39. DropLocalBroadcast bool
  40. DropMulticast bool
  41. EnableGSO bool
  42. EnableGRO bool
  43. GSOMaxSegments int
  44. routines int
  45. MessageMetrics *MessageMetrics
  46. version string
  47. relayManager *relayManager
  48. punchy *Punchy
  49. tryPromoteEvery uint32
  50. reQueryEvery uint32
  51. reQueryWait time.Duration
  52. ConntrackCacheTimeout time.Duration
  53. BatchFlushInterval time.Duration
  54. BatchQueueDepth int
  55. l *logrus.Logger
  56. }
  57. type Interface struct {
  58. hostMap *HostMap
  59. outside udp.Conn
  60. inside overlay.Device
  61. pki *PKI
  62. firewall *Firewall
  63. connectionManager *connectionManager
  64. handshakeManager *HandshakeManager
  65. serveDns bool
  66. createTime time.Time
  67. lightHouse *LightHouse
  68. myBroadcastAddrsTable *bart.Lite
  69. myVpnAddrs []netip.Addr // A list of addresses assigned to us via our certificate
  70. myVpnAddrsTable *bart.Lite
  71. myVpnNetworks []netip.Prefix // A list of networks assigned to us via our certificate
  72. myVpnNetworksTable *bart.Lite
  73. dropLocalBroadcast bool
  74. dropMulticast bool
  75. routines int
  76. disconnectInvalid atomic.Bool
  77. closed atomic.Bool
  78. relayManager *relayManager
  79. tryPromoteEvery atomic.Uint32
  80. reQueryEvery atomic.Uint32
  81. reQueryWait atomic.Int64
  82. sendRecvErrorConfig sendRecvErrorConfig
  83. // rebindCount is used to decide if an active tunnel should trigger a punch notification through a lighthouse
  84. rebindCount int8
  85. version string
  86. conntrackCacheTimeout time.Duration
  87. batchQueueDepth int
  88. enableGSO bool
  89. enableGRO bool
  90. gsoMaxSegments int
  91. batchUDPQueueGauge metrics.Gauge
  92. batchUDPFlushCounter metrics.Counter
  93. batchTunQueueGauge metrics.Gauge
  94. batchTunFlushCounter metrics.Counter
  95. batchFlushInterval atomic.Int64
  96. sendSem chan struct{}
  97. writers []udp.Conn
  98. readers []io.ReadWriteCloser
  99. batches batchPipelines
  100. metricHandshakes metrics.Histogram
  101. messageMetrics *MessageMetrics
  102. cachedPacketMetrics *cachedPacketMetrics
  103. l *logrus.Logger
  104. }
  105. type EncWriter interface {
  106. SendVia(via *HostInfo,
  107. relay *Relay,
  108. ad,
  109. nb,
  110. out []byte,
  111. nocopy bool,
  112. )
  113. SendMessageToVpnAddr(t header.MessageType, st header.MessageSubType, vpnAddr netip.Addr, p, nb, out []byte)
  114. SendMessageToHostInfo(t header.MessageType, st header.MessageSubType, hostinfo *HostInfo, p, nb, out []byte)
  115. Handshake(vpnAddr netip.Addr)
  116. GetHostInfo(vpnAddr netip.Addr) *HostInfo
  117. GetCertState() *CertState
  118. }
  119. type sendRecvErrorConfig uint8
  120. const (
  121. sendRecvErrorAlways sendRecvErrorConfig = iota
  122. sendRecvErrorNever
  123. sendRecvErrorPrivate
  124. )
  125. func (s sendRecvErrorConfig) ShouldSendRecvError(endpoint netip.AddrPort) bool {
  126. switch s {
  127. case sendRecvErrorPrivate:
  128. return endpoint.Addr().IsPrivate()
  129. case sendRecvErrorAlways:
  130. return true
  131. case sendRecvErrorNever:
  132. return false
  133. default:
  134. panic(fmt.Errorf("invalid sendRecvErrorConfig value: %d", s))
  135. }
  136. }
  137. func (s sendRecvErrorConfig) String() string {
  138. switch s {
  139. case sendRecvErrorAlways:
  140. return "always"
  141. case sendRecvErrorNever:
  142. return "never"
  143. case sendRecvErrorPrivate:
  144. return "private"
  145. default:
  146. return fmt.Sprintf("invalid(%d)", s)
  147. }
  148. }
  149. func NewInterface(ctx context.Context, c *InterfaceConfig) (*Interface, error) {
  150. if c.Outside == nil {
  151. return nil, errors.New("no outside connection")
  152. }
  153. if c.Inside == nil {
  154. return nil, errors.New("no inside interface (tun)")
  155. }
  156. if c.pki == nil {
  157. return nil, errors.New("no certificate state")
  158. }
  159. if c.Firewall == nil {
  160. return nil, errors.New("no firewall rules")
  161. }
  162. if c.connectionManager == nil {
  163. return nil, errors.New("no connection manager")
  164. }
  165. if c.GSOMaxSegments <= 0 {
  166. c.GSOMaxSegments = defaultGSOMaxSegments
  167. }
  168. if c.GSOMaxSegments > maxKernelGSOSegments {
  169. c.GSOMaxSegments = maxKernelGSOSegments
  170. }
  171. if c.BatchQueueDepth <= 0 {
  172. c.BatchQueueDepth = c.routines * defaultBatchQueueDepthFactor
  173. }
  174. if c.BatchFlushInterval < 0 {
  175. c.BatchFlushInterval = 0
  176. }
  177. if c.BatchFlushInterval == 0 && c.EnableGSO {
  178. c.BatchFlushInterval = defaultGSOFlushInterval
  179. }
  180. cs := c.pki.getCertState()
  181. ifce := &Interface{
  182. pki: c.pki,
  183. hostMap: c.HostMap,
  184. outside: c.Outside,
  185. inside: c.Inside,
  186. firewall: c.Firewall,
  187. serveDns: c.ServeDns,
  188. handshakeManager: c.HandshakeManager,
  189. createTime: time.Now(),
  190. lightHouse: c.lightHouse,
  191. dropLocalBroadcast: c.DropLocalBroadcast,
  192. dropMulticast: c.DropMulticast,
  193. routines: c.routines,
  194. version: c.version,
  195. writers: make([]udp.Conn, c.routines),
  196. readers: make([]io.ReadWriteCloser, c.routines),
  197. myVpnNetworks: cs.myVpnNetworks,
  198. myVpnNetworksTable: cs.myVpnNetworksTable,
  199. myVpnAddrs: cs.myVpnAddrs,
  200. myVpnAddrsTable: cs.myVpnAddrsTable,
  201. myBroadcastAddrsTable: cs.myVpnBroadcastAddrsTable,
  202. relayManager: c.relayManager,
  203. connectionManager: c.connectionManager,
  204. conntrackCacheTimeout: c.ConntrackCacheTimeout,
  205. batchQueueDepth: c.BatchQueueDepth,
  206. enableGSO: c.EnableGSO,
  207. enableGRO: c.EnableGRO,
  208. gsoMaxSegments: c.GSOMaxSegments,
  209. metricHandshakes: metrics.GetOrRegisterHistogram("handshakes", nil, metrics.NewExpDecaySample(1028, 0.015)),
  210. messageMetrics: c.MessageMetrics,
  211. cachedPacketMetrics: &cachedPacketMetrics{
  212. sent: metrics.GetOrRegisterCounter("hostinfo.cached_packets.sent", nil),
  213. dropped: metrics.GetOrRegisterCounter("hostinfo.cached_packets.dropped", nil),
  214. },
  215. l: c.l,
  216. }
  217. ifce.tryPromoteEvery.Store(c.tryPromoteEvery)
  218. ifce.batchUDPQueueGauge = metrics.GetOrRegisterGauge("batch.udp.queue_depth", nil)
  219. ifce.batchUDPFlushCounter = metrics.GetOrRegisterCounter("batch.udp.flushes", nil)
  220. ifce.batchTunQueueGauge = metrics.GetOrRegisterGauge("batch.tun.queue_depth", nil)
  221. ifce.batchTunFlushCounter = metrics.GetOrRegisterCounter("batch.tun.flushes", nil)
  222. ifce.batchFlushInterval.Store(int64(c.BatchFlushInterval))
  223. ifce.sendSem = make(chan struct{}, c.routines)
  224. ifce.batches.init(c.Inside, c.routines, c.BatchQueueDepth, c.GSOMaxSegments)
  225. ifce.reQueryEvery.Store(c.reQueryEvery)
  226. ifce.reQueryWait.Store(int64(c.reQueryWait))
  227. if c.l.Level >= logrus.DebugLevel {
  228. c.l.WithFields(logrus.Fields{
  229. "enableGSO": c.EnableGSO,
  230. "enableGRO": c.EnableGRO,
  231. "gsoMaxSegments": c.GSOMaxSegments,
  232. "batchQueueDepth": c.BatchQueueDepth,
  233. "batchFlush": c.BatchFlushInterval,
  234. "batching": ifce.batches.Enabled(),
  235. }).Debug("initialized batch pipelines")
  236. }
  237. ifce.connectionManager.intf = ifce
  238. return ifce, nil
  239. }
  240. // activate creates the interface on the host. After the interface is created, any
  241. // other services that want to bind listeners to its IP may do so successfully. However,
  242. // the interface isn't going to process anything until run() is called.
  243. func (f *Interface) activate() {
  244. // actually turn on tun dev
  245. addr, err := f.outside.LocalAddr()
  246. if err != nil {
  247. f.l.WithError(err).Error("Failed to get udp listen address")
  248. }
  249. f.l.WithField("interface", f.inside.Name()).WithField("networks", f.myVpnNetworks).
  250. WithField("build", f.version).WithField("udpAddr", addr).
  251. WithField("boringcrypto", boringEnabled()).
  252. Info("Nebula interface is active")
  253. metrics.GetOrRegisterGauge("routines", nil).Update(int64(f.routines))
  254. // Prepare n tun queues
  255. var reader io.ReadWriteCloser = f.inside
  256. for i := 0; i < f.routines; i++ {
  257. if i > 0 {
  258. reader, err = f.inside.NewMultiQueueReader()
  259. if err != nil {
  260. f.l.Fatal(err)
  261. }
  262. }
  263. f.readers[i] = reader
  264. }
  265. if err := f.inside.Activate(); err != nil {
  266. f.inside.Close()
  267. f.l.Fatal(err)
  268. }
  269. }
  270. func (f *Interface) run() {
  271. // Launch n queues to read packets from udp
  272. for i := 0; i < f.routines; i++ {
  273. go f.listenOut(i)
  274. }
  275. if f.l.Level >= logrus.DebugLevel {
  276. f.l.WithField("batching", f.batches.Enabled()).Debug("starting interface run loops")
  277. }
  278. if f.batches.Enabled() {
  279. for i := 0; i < f.routines; i++ {
  280. go f.runInsideBatchWorker(i)
  281. go f.runTunWriteQueue(i)
  282. go f.runSendQueue(i)
  283. }
  284. }
  285. // Launch n queues to read packets from tun dev
  286. for i := 0; i < f.routines; i++ {
  287. go f.listenIn(f.readers[i], i)
  288. }
  289. }
  290. func (f *Interface) listenOut(i int) {
  291. runtime.LockOSThread()
  292. var li udp.Conn
  293. if i > 0 {
  294. li = f.writers[i]
  295. } else {
  296. li = f.outside
  297. }
  298. ctCache := firewall.NewConntrackCacheTicker(f.conntrackCacheTimeout)
  299. lhh := f.lightHouse.NewRequestHandler()
  300. plaintext := make([]byte, udp.MTU)
  301. h := &header.H{}
  302. fwPacket := &firewall.Packet{}
  303. nb := make([]byte, 12, 12)
  304. li.ListenOut(func(fromUdpAddr netip.AddrPort, payload []byte) {
  305. f.readOutsidePackets(fromUdpAddr, nil, plaintext[:0], payload, h, fwPacket, lhh, nb, i, ctCache.Get(f.l))
  306. })
  307. }
  308. func (f *Interface) listenIn(reader io.ReadWriteCloser, i int) {
  309. runtime.LockOSThread()
  310. if f.batches.Enabled() {
  311. if br, ok := reader.(overlay.BatchReader); ok {
  312. f.listenInBatchLocked(reader, br, i)
  313. return
  314. }
  315. }
  316. f.listenInLegacyLocked(reader, i)
  317. }
  318. func (f *Interface) listenInLegacyLocked(reader io.ReadWriteCloser, i int) {
  319. packet := make([]byte, mtu)
  320. out := make([]byte, mtu)
  321. fwPacket := &firewall.Packet{}
  322. nb := make([]byte, 12, 12)
  323. conntrackCache := firewall.NewConntrackCacheTicker(f.conntrackCacheTimeout)
  324. for {
  325. n, err := reader.Read(packet)
  326. if err != nil {
  327. if errors.Is(err, os.ErrClosed) && f.closed.Load() {
  328. return
  329. }
  330. f.l.WithError(err).Error("Error while reading outbound packet")
  331. // This only seems to happen when something fatal happens to the fd, so exit.
  332. os.Exit(2)
  333. }
  334. f.consumeInsidePacket(packet[:n], fwPacket, nb, out, i, conntrackCache.Get(f.l))
  335. }
  336. }
  337. func (f *Interface) listenInBatchLocked(raw io.ReadWriteCloser, reader overlay.BatchReader, i int) {
  338. pool := f.batches.Pool()
  339. if pool == nil {
  340. f.l.Warn("batch pipeline enabled without an allocated pool; falling back to single-packet reads")
  341. f.listenInLegacyLocked(raw, i)
  342. return
  343. }
  344. for {
  345. packets, err := reader.ReadIntoBatch(pool)
  346. if err != nil {
  347. if errors.Is(err, os.ErrClosed) && f.closed.Load() {
  348. return
  349. }
  350. f.l.WithError(err).Error("Error while reading outbound packet batch")
  351. os.Exit(2)
  352. }
  353. if len(packets) == 0 {
  354. continue
  355. }
  356. for _, pkt := range packets {
  357. if pkt == nil {
  358. continue
  359. }
  360. if !f.batches.enqueueRx(i, pkt) {
  361. pkt.Release()
  362. }
  363. }
  364. }
  365. }
  366. func (f *Interface) runInsideBatchWorker(i int) {
  367. queue := f.batches.rxQueue(i)
  368. if queue == nil {
  369. return
  370. }
  371. out := make([]byte, mtu)
  372. fwPacket := &firewall.Packet{}
  373. nb := make([]byte, 12, 12)
  374. conntrackCache := firewall.NewConntrackCacheTicker(f.conntrackCacheTimeout)
  375. for pkt := range queue {
  376. if pkt == nil {
  377. continue
  378. }
  379. f.consumeInsidePacket(pkt.Payload(), fwPacket, nb, out, i, conntrackCache.Get(f.l))
  380. pkt.Release()
  381. }
  382. }
  383. func (f *Interface) runSendQueue(i int) {
  384. queue := f.batches.txQueue(i)
  385. if queue == nil {
  386. if f.l.Level >= logrus.DebugLevel {
  387. f.l.WithField("queue", i).Debug("tx queue not initialized; batching disabled for writer")
  388. }
  389. return
  390. }
  391. writer := f.writerForIndex(i)
  392. if writer == nil {
  393. if f.l.Level >= logrus.DebugLevel {
  394. f.l.WithField("queue", i).Debug("no UDP writer for batch queue")
  395. }
  396. return
  397. }
  398. if f.l.Level >= logrus.DebugLevel {
  399. f.l.WithField("queue", i).Debug("send queue worker started")
  400. }
  401. defer func() {
  402. if f.l.Level >= logrus.WarnLevel {
  403. f.l.WithField("queue", i).Warn("send queue worker exited")
  404. }
  405. }()
  406. batchCap := f.batches.batchSizeHint()
  407. if batchCap <= 0 {
  408. batchCap = 1
  409. }
  410. gsoLimit := f.effectiveGSOMaxSegments()
  411. if gsoLimit > batchCap {
  412. batchCap = gsoLimit
  413. }
  414. pending := make([]queuedDatagram, 0, batchCap)
  415. var (
  416. flushTimer *time.Timer
  417. flushC <-chan time.Time
  418. )
  419. dispatch := func(reason string, timerFired bool) {
  420. if len(pending) == 0 {
  421. return
  422. }
  423. batch := pending
  424. f.flushAndReleaseBatch(i, writer, batch, reason)
  425. for idx := range batch {
  426. batch[idx] = queuedDatagram{}
  427. }
  428. pending = pending[:0]
  429. if flushTimer != nil {
  430. if !timerFired {
  431. if !flushTimer.Stop() {
  432. select {
  433. case <-flushTimer.C:
  434. default:
  435. }
  436. }
  437. }
  438. flushTimer = nil
  439. flushC = nil
  440. }
  441. }
  442. armTimer := func() {
  443. delay := f.currentBatchFlushInterval()
  444. if delay <= 0 {
  445. dispatch("nogso", false)
  446. return
  447. }
  448. if flushTimer == nil {
  449. flushTimer = time.NewTimer(delay)
  450. flushC = flushTimer.C
  451. }
  452. }
  453. for {
  454. select {
  455. case d := <-queue:
  456. if d.packet == nil {
  457. continue
  458. }
  459. if f.l.Level >= logrus.DebugLevel {
  460. f.l.WithFields(logrus.Fields{
  461. "queue": i,
  462. "payload_len": d.packet.Len,
  463. "dest": d.addr,
  464. }).Debug("send queue received packet")
  465. }
  466. pending = append(pending, d)
  467. if gsoLimit > 0 && len(pending) >= gsoLimit {
  468. dispatch("gso", false)
  469. continue
  470. }
  471. if len(pending) >= cap(pending) {
  472. dispatch("cap", false)
  473. continue
  474. }
  475. armTimer()
  476. f.observeUDPQueueLen(i)
  477. case <-flushC:
  478. dispatch("timer", true)
  479. }
  480. }
  481. }
  482. func (f *Interface) runTunWriteQueue(i int) {
  483. queue := f.batches.tunQueue(i)
  484. if queue == nil {
  485. return
  486. }
  487. writer := f.batches.inside
  488. if writer == nil {
  489. return
  490. }
  491. batchCap := f.batches.batchSizeHint()
  492. if batchCap <= 0 {
  493. batchCap = 1
  494. }
  495. pending := make([]*overlay.Packet, 0, batchCap)
  496. var (
  497. flushTimer *time.Timer
  498. flushC <-chan time.Time
  499. )
  500. flush := func(reason string, timerFired bool) {
  501. if len(pending) == 0 {
  502. return
  503. }
  504. if _, err := writer.WriteBatch(pending); err != nil {
  505. f.l.WithError(err).
  506. WithField("queue", i).
  507. WithField("reason", reason).
  508. Warn("Failed to write tun batch")
  509. }
  510. for idx := range pending {
  511. if pending[idx] != nil {
  512. pending[idx].Release()
  513. }
  514. }
  515. pending = pending[:0]
  516. if flushTimer != nil {
  517. if !timerFired {
  518. if !flushTimer.Stop() {
  519. select {
  520. case <-flushTimer.C:
  521. default:
  522. }
  523. }
  524. }
  525. flushTimer = nil
  526. flushC = nil
  527. }
  528. }
  529. armTimer := func() {
  530. delay := f.currentBatchFlushInterval()
  531. if delay <= 0 {
  532. return
  533. }
  534. if flushTimer == nil {
  535. flushTimer = time.NewTimer(delay)
  536. flushC = flushTimer.C
  537. }
  538. }
  539. for {
  540. select {
  541. case pkt := <-queue:
  542. if pkt == nil {
  543. continue
  544. }
  545. pending = append(pending, pkt)
  546. if len(pending) >= cap(pending) {
  547. flush("cap", false)
  548. continue
  549. }
  550. armTimer()
  551. f.observeTunQueueLen(i)
  552. case <-flushC:
  553. flush("timer", true)
  554. }
  555. }
  556. }
  557. func (f *Interface) flushAndReleaseBatch(index int, writer udp.Conn, batch []queuedDatagram, reason string) {
  558. if len(batch) == 0 {
  559. return
  560. }
  561. f.flushDatagrams(index, writer, batch, reason)
  562. for idx := range batch {
  563. if batch[idx].packet != nil {
  564. batch[idx].packet.Release()
  565. batch[idx].packet = nil
  566. }
  567. }
  568. if f.batchUDPFlushCounter != nil {
  569. f.batchUDPFlushCounter.Inc(int64(len(batch)))
  570. }
  571. }
  572. func (f *Interface) flushDatagrams(index int, writer udp.Conn, batch []queuedDatagram, reason string) {
  573. if len(batch) == 0 {
  574. return
  575. }
  576. if f.l.Level >= logrus.DebugLevel {
  577. f.l.WithFields(logrus.Fields{
  578. "writer": index,
  579. "reason": reason,
  580. "pending": len(batch),
  581. }).Debug("udp batch flush summary")
  582. }
  583. maxSeg := f.effectiveGSOMaxSegments()
  584. if bw, ok := writer.(udp.BatchConn); ok {
  585. chunkCap := maxSeg
  586. if chunkCap <= 0 {
  587. chunkCap = len(batch)
  588. }
  589. chunk := make([]udp.Datagram, 0, chunkCap)
  590. var (
  591. currentAddr netip.AddrPort
  592. segments int
  593. )
  594. flushChunk := func() {
  595. if len(chunk) == 0 {
  596. return
  597. }
  598. if f.l.Level >= logrus.DebugLevel {
  599. f.l.WithFields(logrus.Fields{
  600. "writer": index,
  601. "segments": len(chunk),
  602. "dest": chunk[0].Addr,
  603. "reason": reason,
  604. "pending_total": len(batch),
  605. }).Debug("flushing UDP batch")
  606. }
  607. if err := bw.WriteBatch(chunk); err != nil {
  608. f.l.WithError(err).
  609. WithField("writer", index).
  610. WithField("reason", reason).
  611. Warn("Failed to write UDP batch")
  612. }
  613. chunk = chunk[:0]
  614. segments = 0
  615. }
  616. for _, item := range batch {
  617. if item.packet == nil || !item.addr.IsValid() {
  618. continue
  619. }
  620. payload := item.packet.Payload()[:item.packet.Len]
  621. if segments == 0 {
  622. currentAddr = item.addr
  623. }
  624. if item.addr != currentAddr || (maxSeg > 0 && segments >= maxSeg) {
  625. flushChunk()
  626. currentAddr = item.addr
  627. }
  628. chunk = append(chunk, udp.Datagram{Payload: payload, Addr: item.addr})
  629. segments++
  630. }
  631. flushChunk()
  632. return
  633. }
  634. for _, item := range batch {
  635. if item.packet == nil || !item.addr.IsValid() {
  636. continue
  637. }
  638. if f.l.Level >= logrus.DebugLevel {
  639. f.l.WithFields(logrus.Fields{
  640. "writer": index,
  641. "reason": reason,
  642. "dest": item.addr,
  643. "segments": 1,
  644. }).Debug("flushing UDP batch")
  645. }
  646. if err := writer.WriteTo(item.packet.Payload()[:item.packet.Len], item.addr); err != nil {
  647. f.l.WithError(err).
  648. WithField("writer", index).
  649. WithField("udpAddr", item.addr).
  650. WithField("reason", reason).
  651. Warn("Failed to write UDP packet")
  652. }
  653. }
  654. }
  655. func (f *Interface) tryQueueDatagram(q int, buf []byte, addr netip.AddrPort) bool {
  656. if !addr.IsValid() || !f.batches.Enabled() {
  657. return false
  658. }
  659. pkt := f.batches.newPacket()
  660. if pkt == nil {
  661. return false
  662. }
  663. payload := pkt.Payload()
  664. if len(payload) < len(buf) {
  665. pkt.Release()
  666. return false
  667. }
  668. copy(payload, buf)
  669. pkt.Len = len(buf)
  670. if f.batches.enqueueTx(q, pkt, addr) {
  671. f.observeUDPQueueLen(q)
  672. return true
  673. }
  674. pkt.Release()
  675. return false
  676. }
  677. func (f *Interface) writerForIndex(i int) udp.Conn {
  678. if i < 0 || i >= len(f.writers) {
  679. return nil
  680. }
  681. return f.writers[i]
  682. }
  683. func (f *Interface) writeImmediate(q int, buf []byte, addr netip.AddrPort, hostinfo *HostInfo) {
  684. writer := f.writerForIndex(q)
  685. if writer == nil {
  686. f.l.WithField("udpAddr", addr).
  687. WithField("writer", q).
  688. Error("Failed to write outgoing packet: no writer available")
  689. return
  690. }
  691. if err := writer.WriteTo(buf, addr); err != nil {
  692. hostinfo.logger(f.l).
  693. WithError(err).
  694. WithField("udpAddr", addr).
  695. Error("Failed to write outgoing packet")
  696. }
  697. }
  698. func (f *Interface) tryQueuePacket(q int, pkt *overlay.Packet, addr netip.AddrPort) bool {
  699. if pkt == nil || !addr.IsValid() || !f.batches.Enabled() {
  700. return false
  701. }
  702. if f.batches.enqueueTx(q, pkt, addr) {
  703. f.observeUDPQueueLen(q)
  704. return true
  705. }
  706. return false
  707. }
  708. func (f *Interface) writeImmediatePacket(q int, pkt *overlay.Packet, addr netip.AddrPort, hostinfo *HostInfo) {
  709. if pkt == nil {
  710. return
  711. }
  712. writer := f.writerForIndex(q)
  713. if writer == nil {
  714. f.l.WithField("udpAddr", addr).
  715. WithField("writer", q).
  716. Error("Failed to write outgoing packet: no writer available")
  717. pkt.Release()
  718. return
  719. }
  720. if err := writer.WriteTo(pkt.Payload()[:pkt.Len], addr); err != nil {
  721. hostinfo.logger(f.l).
  722. WithError(err).
  723. WithField("udpAddr", addr).
  724. Error("Failed to write outgoing packet")
  725. }
  726. pkt.Release()
  727. }
  728. func (f *Interface) writePacketToTun(q int, pkt *overlay.Packet) {
  729. if pkt == nil {
  730. return
  731. }
  732. writer := f.readers[q]
  733. if writer == nil {
  734. pkt.Release()
  735. return
  736. }
  737. if _, err := writer.Write(pkt.Payload()[:pkt.Len]); err != nil {
  738. f.l.WithError(err).Error("Failed to write to tun")
  739. }
  740. pkt.Release()
  741. }
  742. func (f *Interface) observeUDPQueueLen(i int) {
  743. if f.batchUDPQueueGauge == nil {
  744. return
  745. }
  746. f.batchUDPQueueGauge.Update(int64(f.batches.txQueueLen(i)))
  747. }
  748. func (f *Interface) observeTunQueueLen(i int) {
  749. if f.batchTunQueueGauge == nil {
  750. return
  751. }
  752. f.batchTunQueueGauge.Update(int64(f.batches.tunQueueLen(i)))
  753. }
  754. func (f *Interface) currentBatchFlushInterval() time.Duration {
  755. if v := f.batchFlushInterval.Load(); v > 0 {
  756. return time.Duration(v)
  757. }
  758. return 0
  759. }
  760. func (f *Interface) effectiveGSOMaxSegments() int {
  761. max := f.gsoMaxSegments
  762. if max <= 0 {
  763. max = defaultGSOMaxSegments
  764. }
  765. if max > maxKernelGSOSegments {
  766. max = maxKernelGSOSegments
  767. }
  768. if !f.enableGSO {
  769. return 1
  770. }
  771. return max
  772. }
  773. type udpOffloadConfigurator interface {
  774. ConfigureOffload(enableGSO, enableGRO bool, maxSegments int)
  775. }
  776. func (f *Interface) applyOffloadConfig(enableGSO, enableGRO bool, maxSegments int) {
  777. if maxSegments <= 0 {
  778. maxSegments = defaultGSOMaxSegments
  779. }
  780. if maxSegments > maxKernelGSOSegments {
  781. maxSegments = maxKernelGSOSegments
  782. }
  783. f.enableGSO = enableGSO
  784. f.enableGRO = enableGRO
  785. f.gsoMaxSegments = maxSegments
  786. for _, writer := range f.writers {
  787. if cfg, ok := writer.(udpOffloadConfigurator); ok {
  788. cfg.ConfigureOffload(enableGSO, enableGRO, maxSegments)
  789. }
  790. }
  791. }
  792. func (f *Interface) RegisterConfigChangeCallbacks(c *config.C) {
  793. c.RegisterReloadCallback(f.reloadFirewall)
  794. c.RegisterReloadCallback(f.reloadSendRecvError)
  795. c.RegisterReloadCallback(f.reloadDisconnectInvalid)
  796. c.RegisterReloadCallback(f.reloadMisc)
  797. for _, udpConn := range f.writers {
  798. c.RegisterReloadCallback(udpConn.ReloadConfig)
  799. }
  800. }
  801. func (f *Interface) reloadDisconnectInvalid(c *config.C) {
  802. initial := c.InitialLoad()
  803. if initial || c.HasChanged("pki.disconnect_invalid") {
  804. f.disconnectInvalid.Store(c.GetBool("pki.disconnect_invalid", true))
  805. if !initial {
  806. f.l.Infof("pki.disconnect_invalid changed to %v", f.disconnectInvalid.Load())
  807. }
  808. }
  809. }
  810. func (f *Interface) reloadFirewall(c *config.C) {
  811. //TODO: need to trigger/detect if the certificate changed too
  812. if c.HasChanged("firewall") == false {
  813. f.l.Debug("No firewall config change detected")
  814. return
  815. }
  816. fw, err := NewFirewallFromConfig(f.l, f.pki.getCertState(), c)
  817. if err != nil {
  818. f.l.WithError(err).Error("Error while creating firewall during reload")
  819. return
  820. }
  821. oldFw := f.firewall
  822. conntrack := oldFw.Conntrack
  823. conntrack.Lock()
  824. defer conntrack.Unlock()
  825. fw.rulesVersion = oldFw.rulesVersion + 1
  826. // If rulesVersion is back to zero, we have wrapped all the way around. Be
  827. // safe and just reset conntrack in this case.
  828. if fw.rulesVersion == 0 {
  829. f.l.WithField("firewallHashes", fw.GetRuleHashes()).
  830. WithField("oldFirewallHashes", oldFw.GetRuleHashes()).
  831. WithField("rulesVersion", fw.rulesVersion).
  832. Warn("firewall rulesVersion has overflowed, resetting conntrack")
  833. } else {
  834. fw.Conntrack = conntrack
  835. }
  836. f.firewall = fw
  837. oldFw.Destroy()
  838. f.l.WithField("firewallHashes", fw.GetRuleHashes()).
  839. WithField("oldFirewallHashes", oldFw.GetRuleHashes()).
  840. WithField("rulesVersion", fw.rulesVersion).
  841. Info("New firewall has been installed")
  842. }
  843. func (f *Interface) reloadSendRecvError(c *config.C) {
  844. if c.InitialLoad() || c.HasChanged("listen.send_recv_error") {
  845. stringValue := c.GetString("listen.send_recv_error", "always")
  846. switch stringValue {
  847. case "always":
  848. f.sendRecvErrorConfig = sendRecvErrorAlways
  849. case "never":
  850. f.sendRecvErrorConfig = sendRecvErrorNever
  851. case "private":
  852. f.sendRecvErrorConfig = sendRecvErrorPrivate
  853. default:
  854. if c.GetBool("listen.send_recv_error", true) {
  855. f.sendRecvErrorConfig = sendRecvErrorAlways
  856. } else {
  857. f.sendRecvErrorConfig = sendRecvErrorNever
  858. }
  859. }
  860. f.l.WithField("sendRecvError", f.sendRecvErrorConfig.String()).
  861. Info("Loaded send_recv_error config")
  862. }
  863. }
  864. func (f *Interface) reloadMisc(c *config.C) {
  865. if c.HasChanged("counters.try_promote") {
  866. n := c.GetUint32("counters.try_promote", defaultPromoteEvery)
  867. f.tryPromoteEvery.Store(n)
  868. f.l.Info("counters.try_promote has changed")
  869. }
  870. if c.HasChanged("counters.requery_every_packets") {
  871. n := c.GetUint32("counters.requery_every_packets", defaultReQueryEvery)
  872. f.reQueryEvery.Store(n)
  873. f.l.Info("counters.requery_every_packets has changed")
  874. }
  875. if c.HasChanged("timers.requery_wait_duration") {
  876. n := c.GetDuration("timers.requery_wait_duration", defaultReQueryWait)
  877. f.reQueryWait.Store(int64(n))
  878. f.l.Info("timers.requery_wait_duration has changed")
  879. }
  880. if c.HasChanged("listen.gso_flush_timeout") {
  881. d := c.GetDuration("listen.gso_flush_timeout", defaultGSOFlushInterval)
  882. if d < 0 {
  883. d = 0
  884. }
  885. f.batchFlushInterval.Store(int64(d))
  886. f.l.WithField("duration", d).Info("listen.gso_flush_timeout has changed")
  887. } else if c.HasChanged("batch.flush_interval") {
  888. d := c.GetDuration("batch.flush_interval", defaultGSOFlushInterval)
  889. if d < 0 {
  890. d = 0
  891. }
  892. f.batchFlushInterval.Store(int64(d))
  893. f.l.WithField("duration", d).Warn("batch.flush_interval is deprecated; use listen.gso_flush_timeout")
  894. }
  895. if c.HasChanged("batch.queue_depth") {
  896. n := c.GetInt("batch.queue_depth", f.batchQueueDepth)
  897. if n != f.batchQueueDepth {
  898. f.batchQueueDepth = n
  899. f.l.Warn("batch.queue_depth changes require a restart to take effect")
  900. }
  901. }
  902. if c.HasChanged("listen.enable_gso") || c.HasChanged("listen.enable_gro") || c.HasChanged("listen.gso_max_segments") {
  903. enableGSO := c.GetBool("listen.enable_gso", f.enableGSO)
  904. enableGRO := c.GetBool("listen.enable_gro", f.enableGRO)
  905. maxSeg := c.GetInt("listen.gso_max_segments", f.gsoMaxSegments)
  906. f.applyOffloadConfig(enableGSO, enableGRO, maxSeg)
  907. f.l.WithFields(logrus.Fields{
  908. "enableGSO": enableGSO,
  909. "enableGRO": enableGRO,
  910. "gsoMaxSegments": maxSeg,
  911. }).Info("listen GSO/GRO configuration updated")
  912. }
  913. }
  914. func (f *Interface) emitStats(ctx context.Context, i time.Duration) {
  915. ticker := time.NewTicker(i)
  916. defer ticker.Stop()
  917. udpStats := udp.NewUDPStatsEmitter(f.writers)
  918. certExpirationGauge := metrics.GetOrRegisterGauge("certificate.ttl_seconds", nil)
  919. certInitiatingVersion := metrics.GetOrRegisterGauge("certificate.initiating_version", nil)
  920. certMaxVersion := metrics.GetOrRegisterGauge("certificate.max_version", nil)
  921. for {
  922. select {
  923. case <-ctx.Done():
  924. return
  925. case <-ticker.C:
  926. f.firewall.EmitStats()
  927. f.handshakeManager.EmitStats()
  928. udpStats()
  929. certState := f.pki.getCertState()
  930. defaultCrt := certState.GetDefaultCertificate()
  931. certExpirationGauge.Update(int64(defaultCrt.NotAfter().Sub(time.Now()) / time.Second))
  932. certInitiatingVersion.Update(int64(defaultCrt.Version()))
  933. // Report the max certificate version we are capable of using
  934. if certState.v2Cert != nil {
  935. certMaxVersion.Update(int64(certState.v2Cert.Version()))
  936. } else {
  937. certMaxVersion.Update(int64(certState.v1Cert.Version()))
  938. }
  939. }
  940. }
  941. }
  942. func (f *Interface) GetHostInfo(vpnIp netip.Addr) *HostInfo {
  943. return f.hostMap.QueryVpnAddr(vpnIp)
  944. }
  945. func (f *Interface) GetCertState() *CertState {
  946. return f.pki.getCertState()
  947. }
  948. func (f *Interface) Close() error {
  949. f.closed.Store(true)
  950. for _, u := range f.writers {
  951. err := u.Close()
  952. if err != nil {
  953. f.l.WithError(err).Error("Error while closing udp socket")
  954. }
  955. }
  956. // Release the tun device
  957. return f.inside.Close()
  958. }