interface.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. package nebula
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "net/netip"
  8. "runtime"
  9. "sync"
  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/packet"
  20. "github.com/slackhq/nebula/udp"
  21. )
  22. const (
  23. mtu = 9001
  24. inboundBatchSizeDefault = 32
  25. outboundBatchSizeDefault = 32
  26. batchFlushIntervalDefault = 50 * time.Microsecond
  27. maxOutstandingBatchesDefault = 1028
  28. )
  29. type InterfaceConfig struct {
  30. HostMap *HostMap
  31. Outside udp.Conn
  32. Inside overlay.Device
  33. pki *PKI
  34. Cipher string
  35. Firewall *Firewall
  36. ServeDns bool
  37. HandshakeManager *HandshakeManager
  38. lightHouse *LightHouse
  39. connectionManager *connectionManager
  40. DropLocalBroadcast bool
  41. DropMulticast bool
  42. routines int
  43. MessageMetrics *MessageMetrics
  44. version string
  45. relayManager *relayManager
  46. punchy *Punchy
  47. tryPromoteEvery uint32
  48. reQueryEvery uint32
  49. reQueryWait time.Duration
  50. ConntrackCacheTimeout time.Duration
  51. BatchConfig BatchConfig
  52. l *logrus.Logger
  53. }
  54. type BatchConfig struct {
  55. InboundBatchSize int
  56. OutboundBatchSize int
  57. FlushInterval time.Duration
  58. MaxOutstandingPerChan int
  59. }
  60. type Interface struct {
  61. hostMap *HostMap
  62. outside udp.Conn
  63. inside overlay.Device
  64. pki *PKI
  65. firewall *Firewall
  66. connectionManager *connectionManager
  67. handshakeManager *HandshakeManager
  68. serveDns bool
  69. createTime time.Time
  70. lightHouse *LightHouse
  71. myBroadcastAddrsTable *bart.Lite
  72. myVpnAddrs []netip.Addr // A list of addresses assigned to us via our certificate
  73. myVpnAddrsTable *bart.Lite
  74. myVpnNetworks []netip.Prefix // A list of networks assigned to us via our certificate
  75. myVpnNetworksTable *bart.Lite
  76. dropLocalBroadcast bool
  77. dropMulticast bool
  78. routines int
  79. disconnectInvalid atomic.Bool
  80. closed atomic.Bool
  81. relayManager *relayManager
  82. tryPromoteEvery atomic.Uint32
  83. reQueryEvery atomic.Uint32
  84. reQueryWait atomic.Int64
  85. sendRecvErrorConfig sendRecvErrorConfig
  86. // rebindCount is used to decide if an active tunnel should trigger a punch notification through a lighthouse
  87. rebindCount int8
  88. version string
  89. conntrackCacheTimeout time.Duration
  90. writers []udp.Conn
  91. readers []io.ReadWriteCloser
  92. wg sync.WaitGroup
  93. metricHandshakes metrics.Histogram
  94. messageMetrics *MessageMetrics
  95. cachedPacketMetrics *cachedPacketMetrics
  96. l *logrus.Logger
  97. inPool sync.Pool
  98. inbound []chan *packetBatch
  99. outPool sync.Pool
  100. outbound []chan *outboundBatch
  101. packetBatchPool sync.Pool
  102. outboundBatchPool sync.Pool
  103. inboundBatchSize int
  104. outboundBatchSize int
  105. batchFlushInterval time.Duration
  106. maxOutstandingPerChan int
  107. }
  108. type packetBatch struct {
  109. packets []*packet.Packet
  110. }
  111. func newPacketBatch(capacity int) *packetBatch {
  112. return &packetBatch{
  113. packets: make([]*packet.Packet, 0, capacity),
  114. }
  115. }
  116. func (b *packetBatch) add(p *packet.Packet) {
  117. b.packets = append(b.packets, p)
  118. }
  119. func (b *packetBatch) reset() {
  120. for i := range b.packets {
  121. b.packets[i] = nil
  122. }
  123. b.packets = b.packets[:0]
  124. }
  125. func (f *Interface) getPacketBatch() *packetBatch {
  126. if v := f.packetBatchPool.Get(); v != nil {
  127. b := v.(*packetBatch)
  128. b.reset()
  129. return b
  130. }
  131. return newPacketBatch(f.inboundBatchSize)
  132. }
  133. func (f *Interface) releasePacketBatch(b *packetBatch) {
  134. b.reset()
  135. f.packetBatchPool.Put(b)
  136. }
  137. type outboundBatch struct {
  138. payloads []*[]byte
  139. }
  140. func newOutboundBatch(capacity int) *outboundBatch {
  141. return &outboundBatch{payloads: make([]*[]byte, 0, capacity)}
  142. }
  143. func (b *outboundBatch) add(buf *[]byte) {
  144. b.payloads = append(b.payloads, buf)
  145. }
  146. func (b *outboundBatch) reset() {
  147. for i := range b.payloads {
  148. b.payloads[i] = nil
  149. }
  150. b.payloads = b.payloads[:0]
  151. }
  152. func (f *Interface) getOutboundBatch() *outboundBatch {
  153. if v := f.outboundBatchPool.Get(); v != nil {
  154. b := v.(*outboundBatch)
  155. b.reset()
  156. return b
  157. }
  158. return newOutboundBatch(f.outboundBatchSize)
  159. }
  160. func (f *Interface) releaseOutboundBatch(b *outboundBatch) {
  161. b.reset()
  162. f.outboundBatchPool.Put(b)
  163. }
  164. type EncWriter interface {
  165. SendVia(via *HostInfo,
  166. relay *Relay,
  167. ad,
  168. nb,
  169. out []byte,
  170. nocopy bool,
  171. )
  172. SendMessageToVpnAddr(t header.MessageType, st header.MessageSubType, vpnAddr netip.Addr, p, nb, out []byte)
  173. SendMessageToHostInfo(t header.MessageType, st header.MessageSubType, hostinfo *HostInfo, p, nb, out []byte)
  174. Handshake(vpnAddr netip.Addr)
  175. GetHostInfo(vpnAddr netip.Addr) *HostInfo
  176. GetCertState() *CertState
  177. }
  178. type sendRecvErrorConfig uint8
  179. const (
  180. sendRecvErrorAlways sendRecvErrorConfig = iota
  181. sendRecvErrorNever
  182. sendRecvErrorPrivate
  183. )
  184. func (s sendRecvErrorConfig) ShouldSendRecvError(endpoint netip.AddrPort) bool {
  185. switch s {
  186. case sendRecvErrorPrivate:
  187. return endpoint.Addr().IsPrivate()
  188. case sendRecvErrorAlways:
  189. return true
  190. case sendRecvErrorNever:
  191. return false
  192. default:
  193. panic(fmt.Errorf("invalid sendRecvErrorConfig value: %d", s))
  194. }
  195. }
  196. func (s sendRecvErrorConfig) String() string {
  197. switch s {
  198. case sendRecvErrorAlways:
  199. return "always"
  200. case sendRecvErrorNever:
  201. return "never"
  202. case sendRecvErrorPrivate:
  203. return "private"
  204. default:
  205. return fmt.Sprintf("invalid(%d)", s)
  206. }
  207. }
  208. func NewInterface(ctx context.Context, c *InterfaceConfig) (*Interface, error) {
  209. if c.Outside == nil {
  210. return nil, errors.New("no outside connection")
  211. }
  212. if c.Inside == nil {
  213. return nil, errors.New("no inside interface (tun)")
  214. }
  215. if c.pki == nil {
  216. return nil, errors.New("no certificate state")
  217. }
  218. if c.Firewall == nil {
  219. return nil, errors.New("no firewall rules")
  220. }
  221. if c.connectionManager == nil {
  222. return nil, errors.New("no connection manager")
  223. }
  224. cs := c.pki.getCertState()
  225. bc := c.BatchConfig
  226. if bc.InboundBatchSize <= 0 {
  227. bc.InboundBatchSize = inboundBatchSizeDefault
  228. }
  229. if bc.OutboundBatchSize <= 0 {
  230. bc.OutboundBatchSize = outboundBatchSizeDefault
  231. }
  232. if bc.FlushInterval <= 0 {
  233. bc.FlushInterval = batchFlushIntervalDefault
  234. }
  235. if bc.MaxOutstandingPerChan <= 0 {
  236. bc.MaxOutstandingPerChan = maxOutstandingBatchesDefault
  237. }
  238. ifce := &Interface{
  239. pki: c.pki,
  240. hostMap: c.HostMap,
  241. outside: c.Outside,
  242. inside: c.Inside,
  243. firewall: c.Firewall,
  244. serveDns: c.ServeDns,
  245. handshakeManager: c.HandshakeManager,
  246. createTime: time.Now(),
  247. lightHouse: c.lightHouse,
  248. dropLocalBroadcast: c.DropLocalBroadcast,
  249. dropMulticast: c.DropMulticast,
  250. routines: c.routines,
  251. version: c.version,
  252. writers: make([]udp.Conn, c.routines),
  253. readers: make([]io.ReadWriteCloser, c.routines),
  254. myVpnNetworks: cs.myVpnNetworks,
  255. myVpnNetworksTable: cs.myVpnNetworksTable,
  256. myVpnAddrs: cs.myVpnAddrs,
  257. myVpnAddrsTable: cs.myVpnAddrsTable,
  258. myBroadcastAddrsTable: cs.myVpnBroadcastAddrsTable,
  259. relayManager: c.relayManager,
  260. connectionManager: c.connectionManager,
  261. conntrackCacheTimeout: c.ConntrackCacheTimeout,
  262. metricHandshakes: metrics.GetOrRegisterHistogram("handshakes", nil, metrics.NewExpDecaySample(1028, 0.015)),
  263. messageMetrics: c.MessageMetrics,
  264. cachedPacketMetrics: &cachedPacketMetrics{
  265. sent: metrics.GetOrRegisterCounter("hostinfo.cached_packets.sent", nil),
  266. dropped: metrics.GetOrRegisterCounter("hostinfo.cached_packets.dropped", nil),
  267. },
  268. inbound: make([]chan *packetBatch, c.routines),
  269. outbound: make([]chan *outboundBatch, c.routines),
  270. l: c.l,
  271. inboundBatchSize: bc.InboundBatchSize,
  272. outboundBatchSize: bc.OutboundBatchSize,
  273. batchFlushInterval: bc.FlushInterval,
  274. maxOutstandingPerChan: bc.MaxOutstandingPerChan,
  275. }
  276. for i := 0; i < c.routines; i++ {
  277. ifce.inbound[i] = make(chan *packetBatch, ifce.maxOutstandingPerChan)
  278. ifce.outbound[i] = make(chan *outboundBatch, ifce.maxOutstandingPerChan)
  279. }
  280. ifce.inPool = sync.Pool{New: func() any {
  281. return packet.New()
  282. }}
  283. ifce.outPool = sync.Pool{New: func() any {
  284. t := make([]byte, mtu)
  285. return &t
  286. }}
  287. ifce.packetBatchPool = sync.Pool{New: func() any {
  288. return newPacketBatch(ifce.inboundBatchSize)
  289. }}
  290. ifce.outboundBatchPool = sync.Pool{New: func() any {
  291. return newOutboundBatch(ifce.outboundBatchSize)
  292. }}
  293. ifce.tryPromoteEvery.Store(c.tryPromoteEvery)
  294. ifce.reQueryEvery.Store(c.reQueryEvery)
  295. ifce.reQueryWait.Store(int64(c.reQueryWait))
  296. ifce.connectionManager.intf = ifce
  297. return ifce, nil
  298. }
  299. // activate creates the interface on the host. After the interface is created, any
  300. // other services that want to bind listeners to its IP may do so successfully. However,
  301. // the interface isn't going to process anything until run() is called.
  302. func (f *Interface) activate() error {
  303. // actually turn on tun dev
  304. addr, err := f.outside.LocalAddr()
  305. if err != nil {
  306. f.l.WithError(err).Error("Failed to get udp listen address")
  307. }
  308. f.l.WithField("interface", f.inside.Name()).WithField("networks", f.myVpnNetworks).
  309. WithField("build", f.version).WithField("udpAddr", addr).
  310. WithField("boringcrypto", boringEnabled()).
  311. Info("Nebula interface is active")
  312. metrics.GetOrRegisterGauge("routines", nil).Update(int64(f.routines))
  313. // Prepare n tun queues
  314. var reader io.ReadWriteCloser = f.inside
  315. for i := 0; i < f.routines; i++ {
  316. if i > 0 {
  317. reader, err = f.inside.NewMultiQueueReader()
  318. if err != nil {
  319. return err
  320. }
  321. }
  322. f.readers[i] = reader
  323. }
  324. if err = f.inside.Activate(); err != nil {
  325. f.inside.Close()
  326. return err
  327. }
  328. return nil
  329. }
  330. func (f *Interface) run(c context.Context) (func(), error) {
  331. for i := 0; i < f.routines; i++ {
  332. // Launch n queues to read packets from udp
  333. f.wg.Add(1)
  334. go f.listenOut(i)
  335. // Launch n queues to read packets from tun dev
  336. f.wg.Add(1)
  337. go f.listenIn(f.readers[i], i)
  338. // Launch n queues to read packets from tun dev
  339. f.wg.Add(1)
  340. go f.workerIn(i, c)
  341. // Launch n queues to read packets from tun dev
  342. f.wg.Add(1)
  343. go f.workerOut(i, c)
  344. }
  345. return f.wg.Wait, nil
  346. }
  347. func (f *Interface) listenOut(i int) {
  348. runtime.LockOSThread()
  349. var li udp.Conn
  350. if i > 0 {
  351. li = f.writers[i]
  352. } else {
  353. li = f.outside
  354. }
  355. batch := f.getPacketBatch()
  356. lastFlush := time.Now()
  357. flush := func(force bool) {
  358. if len(batch.packets) == 0 {
  359. if force {
  360. f.releasePacketBatch(batch)
  361. }
  362. return
  363. }
  364. f.inbound[i] <- batch
  365. batch = f.getPacketBatch()
  366. lastFlush = time.Now()
  367. }
  368. err := li.ListenOut(func(fromUdpAddr netip.AddrPort, payload []byte) {
  369. p := f.inPool.Get().(*packet.Packet)
  370. p.Payload = p.Payload[:mtu]
  371. copy(p.Payload, payload)
  372. p.Payload = p.Payload[:len(payload)]
  373. p.Addr = fromUdpAddr
  374. batch.add(p)
  375. if len(batch.packets) >= f.inboundBatchSize || time.Since(lastFlush) >= f.batchFlushInterval {
  376. flush(false)
  377. }
  378. })
  379. if len(batch.packets) > 0 {
  380. f.inbound[i] <- batch
  381. } else {
  382. f.releasePacketBatch(batch)
  383. }
  384. if err != nil && !f.closed.Load() {
  385. f.l.WithError(err).Error("Error while reading packet inbound packet, closing")
  386. //TODO: Trigger Control to close
  387. }
  388. f.l.Debugf("underlay reader %v is done", i)
  389. f.wg.Done()
  390. }
  391. func (f *Interface) listenIn(reader io.ReadWriteCloser, i int) {
  392. runtime.LockOSThread()
  393. batch := f.getOutboundBatch()
  394. lastFlush := time.Now()
  395. flush := func(force bool) {
  396. if len(batch.payloads) == 0 {
  397. if force {
  398. f.releaseOutboundBatch(batch)
  399. }
  400. return
  401. }
  402. f.outbound[i] <- batch
  403. batch = f.getOutboundBatch()
  404. lastFlush = time.Now()
  405. }
  406. for {
  407. p := f.outPool.Get().(*[]byte)
  408. *p = (*p)[:mtu]
  409. n, err := reader.Read(*p)
  410. if err != nil {
  411. if !f.closed.Load() {
  412. f.l.WithError(err).Error("Error while reading outbound packet, closing")
  413. //TODO: Trigger Control to close
  414. }
  415. break
  416. }
  417. *p = (*p)[:n]
  418. batch.add(p)
  419. if len(batch.payloads) >= f.outboundBatchSize || time.Since(lastFlush) >= f.batchFlushInterval {
  420. flush(false)
  421. }
  422. }
  423. if len(batch.payloads) > 0 {
  424. f.outbound[i] <- batch
  425. } else {
  426. f.releaseOutboundBatch(batch)
  427. }
  428. f.l.Debugf("overlay reader %v is done", i)
  429. f.wg.Done()
  430. }
  431. func (f *Interface) workerIn(i int, ctx context.Context) {
  432. lhh := f.lightHouse.NewRequestHandler()
  433. conntrackCache := firewall.NewConntrackCacheTicker(f.conntrackCacheTimeout)
  434. fwPacket2 := &firewall.Packet{}
  435. nb2 := make([]byte, 12, 12)
  436. result2 := make([]byte, mtu)
  437. h := &header.H{}
  438. for {
  439. select {
  440. case batch := <-f.inbound[i]:
  441. for _, p := range batch.packets {
  442. f.readOutsidePackets(p.Addr, nil, result2[:0], p.Payload, h, fwPacket2, lhh, nb2, i, conntrackCache.Get(f.l))
  443. p.Payload = p.Payload[:mtu]
  444. f.inPool.Put(p)
  445. }
  446. f.releasePacketBatch(batch)
  447. case <-ctx.Done():
  448. f.wg.Done()
  449. return
  450. }
  451. }
  452. }
  453. func (f *Interface) workerOut(i int, ctx context.Context) {
  454. conntrackCache := firewall.NewConntrackCacheTicker(f.conntrackCacheTimeout)
  455. fwPacket1 := &firewall.Packet{}
  456. nb1 := make([]byte, 12, 12)
  457. result1 := make([]byte, mtu)
  458. for {
  459. select {
  460. case batch := <-f.outbound[i]:
  461. for _, data := range batch.payloads {
  462. f.consumeInsidePacket(*data, fwPacket1, nb1, result1, i, conntrackCache.Get(f.l))
  463. *data = (*data)[:mtu]
  464. f.outPool.Put(data)
  465. }
  466. f.releaseOutboundBatch(batch)
  467. case <-ctx.Done():
  468. f.wg.Done()
  469. return
  470. }
  471. }
  472. }
  473. func (f *Interface) RegisterConfigChangeCallbacks(c *config.C) {
  474. c.RegisterReloadCallback(f.reloadFirewall)
  475. c.RegisterReloadCallback(f.reloadSendRecvError)
  476. c.RegisterReloadCallback(f.reloadDisconnectInvalid)
  477. c.RegisterReloadCallback(f.reloadMisc)
  478. for _, udpConn := range f.writers {
  479. c.RegisterReloadCallback(udpConn.ReloadConfig)
  480. }
  481. }
  482. func (f *Interface) reloadDisconnectInvalid(c *config.C) {
  483. initial := c.InitialLoad()
  484. if initial || c.HasChanged("pki.disconnect_invalid") {
  485. f.disconnectInvalid.Store(c.GetBool("pki.disconnect_invalid", true))
  486. if !initial {
  487. f.l.Infof("pki.disconnect_invalid changed to %v", f.disconnectInvalid.Load())
  488. }
  489. }
  490. }
  491. func (f *Interface) reloadFirewall(c *config.C) {
  492. //TODO: need to trigger/detect if the certificate changed too
  493. if c.HasChanged("firewall") == false {
  494. f.l.Debug("No firewall config change detected")
  495. return
  496. }
  497. fw, err := NewFirewallFromConfig(f.l, f.pki.getCertState(), c)
  498. if err != nil {
  499. f.l.WithError(err).Error("Error while creating firewall during reload")
  500. return
  501. }
  502. oldFw := f.firewall
  503. conntrack := oldFw.Conntrack
  504. conntrack.Lock()
  505. defer conntrack.Unlock()
  506. fw.rulesVersion = oldFw.rulesVersion + 1
  507. // If rulesVersion is back to zero, we have wrapped all the way around. Be
  508. // safe and just reset conntrack in this case.
  509. if fw.rulesVersion == 0 {
  510. f.l.WithField("firewallHashes", fw.GetRuleHashes()).
  511. WithField("oldFirewallHashes", oldFw.GetRuleHashes()).
  512. WithField("rulesVersion", fw.rulesVersion).
  513. Warn("firewall rulesVersion has overflowed, resetting conntrack")
  514. } else {
  515. fw.Conntrack = conntrack
  516. }
  517. f.firewall = fw
  518. oldFw.Destroy()
  519. f.l.WithField("firewallHashes", fw.GetRuleHashes()).
  520. WithField("oldFirewallHashes", oldFw.GetRuleHashes()).
  521. WithField("rulesVersion", fw.rulesVersion).
  522. Info("New firewall has been installed")
  523. }
  524. func (f *Interface) reloadSendRecvError(c *config.C) {
  525. if c.InitialLoad() || c.HasChanged("listen.send_recv_error") {
  526. stringValue := c.GetString("listen.send_recv_error", "always")
  527. switch stringValue {
  528. case "always":
  529. f.sendRecvErrorConfig = sendRecvErrorAlways
  530. case "never":
  531. f.sendRecvErrorConfig = sendRecvErrorNever
  532. case "private":
  533. f.sendRecvErrorConfig = sendRecvErrorPrivate
  534. default:
  535. if c.GetBool("listen.send_recv_error", true) {
  536. f.sendRecvErrorConfig = sendRecvErrorAlways
  537. } else {
  538. f.sendRecvErrorConfig = sendRecvErrorNever
  539. }
  540. }
  541. f.l.WithField("sendRecvError", f.sendRecvErrorConfig.String()).
  542. Info("Loaded send_recv_error config")
  543. }
  544. }
  545. func (f *Interface) reloadMisc(c *config.C) {
  546. if c.HasChanged("counters.try_promote") {
  547. n := c.GetUint32("counters.try_promote", defaultPromoteEvery)
  548. f.tryPromoteEvery.Store(n)
  549. f.l.Info("counters.try_promote has changed")
  550. }
  551. if c.HasChanged("counters.requery_every_packets") {
  552. n := c.GetUint32("counters.requery_every_packets", defaultReQueryEvery)
  553. f.reQueryEvery.Store(n)
  554. f.l.Info("counters.requery_every_packets has changed")
  555. }
  556. if c.HasChanged("timers.requery_wait_duration") {
  557. n := c.GetDuration("timers.requery_wait_duration", defaultReQueryWait)
  558. f.reQueryWait.Store(int64(n))
  559. f.l.Info("timers.requery_wait_duration has changed")
  560. }
  561. }
  562. func (f *Interface) emitStats(ctx context.Context, i time.Duration) {
  563. ticker := time.NewTicker(i)
  564. defer ticker.Stop()
  565. udpStats := udp.NewUDPStatsEmitter(f.writers)
  566. certExpirationGauge := metrics.GetOrRegisterGauge("certificate.ttl_seconds", nil)
  567. certInitiatingVersion := metrics.GetOrRegisterGauge("certificate.initiating_version", nil)
  568. certMaxVersion := metrics.GetOrRegisterGauge("certificate.max_version", nil)
  569. for {
  570. select {
  571. case <-ctx.Done():
  572. return
  573. case <-ticker.C:
  574. f.firewall.EmitStats()
  575. f.handshakeManager.EmitStats()
  576. udpStats()
  577. certState := f.pki.getCertState()
  578. defaultCrt := certState.GetDefaultCertificate()
  579. certExpirationGauge.Update(int64(defaultCrt.NotAfter().Sub(time.Now()) / time.Second))
  580. certInitiatingVersion.Update(int64(defaultCrt.Version()))
  581. // Report the max certificate version we are capable of using
  582. if certState.v2Cert != nil {
  583. certMaxVersion.Update(int64(certState.v2Cert.Version()))
  584. } else {
  585. certMaxVersion.Update(int64(certState.v1Cert.Version()))
  586. }
  587. }
  588. }
  589. }
  590. func (f *Interface) GetHostInfo(vpnIp netip.Addr) *HostInfo {
  591. return f.hostMap.QueryVpnAddr(vpnIp)
  592. }
  593. func (f *Interface) GetCertState() *CertState {
  594. return f.pki.getCertState()
  595. }
  596. func (f *Interface) Close() error {
  597. f.closed.Store(true)
  598. // Release the udp readers
  599. for _, u := range f.writers {
  600. err := u.Close()
  601. if err != nil {
  602. f.l.WithError(err).Error("Error while closing udp socket")
  603. }
  604. }
  605. // Release the tun readers
  606. for _, u := range f.readers {
  607. err := u.Close()
  608. if err != nil {
  609. f.l.WithError(err).Error("Error while closing tun device")
  610. }
  611. }
  612. return nil
  613. }