2
0

router.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  1. //go:build e2e_testing
  2. // +build e2e_testing
  3. package router
  4. import (
  5. "context"
  6. "fmt"
  7. "net/netip"
  8. "os"
  9. "path/filepath"
  10. "reflect"
  11. "regexp"
  12. "sort"
  13. "sync"
  14. "testing"
  15. "time"
  16. "github.com/google/gopacket"
  17. "github.com/google/gopacket/layers"
  18. "github.com/slackhq/nebula"
  19. "github.com/slackhq/nebula/header"
  20. "github.com/slackhq/nebula/udp"
  21. "golang.org/x/exp/maps"
  22. )
  23. type R struct {
  24. // Simple map of the ip:port registered on a control to the control
  25. // Basically a router, right?
  26. controls map[netip.AddrPort]*nebula.Control
  27. // A map for inbound packets for a control that doesn't know about this address
  28. inNat map[netip.AddrPort]*nebula.Control
  29. // A last used map, if an inbound packet hit the inNat map then
  30. // all return packets should use the same last used inbound address for the outbound sender
  31. // map[from address + ":" + to address] => ip:port to rewrite in the udp packet to receiver
  32. outNat map[string]netip.AddrPort
  33. // A map of vpn ip to the nebula control it belongs to
  34. vpnControls map[netip.Addr]*nebula.Control
  35. ignoreFlows []ignoreFlow
  36. flow []flowEntry
  37. // A set of additional mermaid graphs to draw in the flow log markdown file
  38. // Currently consisting only of hostmap renders
  39. additionalGraphs []mermaidGraph
  40. // All interactions are locked to help serialize behavior
  41. sync.Mutex
  42. fn string
  43. cancelRender context.CancelFunc
  44. t testing.TB
  45. }
  46. type ignoreFlow struct {
  47. tun NullBool
  48. messageType header.MessageType
  49. subType header.MessageSubType
  50. //from
  51. //to
  52. }
  53. type mermaidGraph struct {
  54. title string
  55. content string
  56. }
  57. type NullBool struct {
  58. HasValue bool
  59. IsTrue bool
  60. }
  61. type flowEntry struct {
  62. note string
  63. packet *packet
  64. }
  65. type packet struct {
  66. from *nebula.Control
  67. to *nebula.Control
  68. packet *udp.Packet
  69. tun bool // a packet pulled off a tun device
  70. rx bool // the packet was received by a udp device
  71. }
  72. func (p *packet) WasReceived() {
  73. if p != nil {
  74. p.rx = true
  75. }
  76. }
  77. type ExitType int
  78. const (
  79. // KeepRouting the function will get called again on the next packet
  80. KeepRouting ExitType = 0
  81. // ExitNow does not route this packet and exits immediately
  82. ExitNow ExitType = 1
  83. // RouteAndExit routes this packet and exits immediately afterwards
  84. RouteAndExit ExitType = 2
  85. )
  86. type ExitFunc func(packet *udp.Packet, receiver *nebula.Control) ExitType
  87. // NewR creates a new router to pass packets in a controlled fashion between the provided controllers.
  88. // The packet flow will be recorded in a file within the mermaid directory under the same name as the test.
  89. // Renders will occur automatically, roughly every 100ms, until a call to RenderFlow() is made
  90. func NewR(t testing.TB, controls ...*nebula.Control) *R {
  91. ctx, cancel := context.WithCancel(context.Background())
  92. if err := os.MkdirAll("mermaid", 0755); err != nil {
  93. panic(err)
  94. }
  95. r := &R{
  96. controls: make(map[netip.AddrPort]*nebula.Control),
  97. vpnControls: make(map[netip.Addr]*nebula.Control),
  98. inNat: make(map[netip.AddrPort]*nebula.Control),
  99. outNat: make(map[string]netip.AddrPort),
  100. flow: []flowEntry{},
  101. ignoreFlows: []ignoreFlow{},
  102. fn: filepath.Join("mermaid", fmt.Sprintf("%s.md", t.Name())),
  103. t: t,
  104. cancelRender: cancel,
  105. }
  106. // Try to remove our render file
  107. os.Remove(r.fn)
  108. for _, c := range controls {
  109. addr := c.GetUDPAddr()
  110. if _, ok := r.controls[addr]; ok {
  111. panic("Duplicate listen address: " + addr.String())
  112. }
  113. for _, vpnAddr := range c.GetVpnAddrs() {
  114. r.vpnControls[vpnAddr] = c
  115. }
  116. r.controls[addr] = c
  117. }
  118. // Spin the renderer in case we go nuts and the test never completes
  119. go func() {
  120. clockSource := time.NewTicker(time.Millisecond * 100)
  121. defer clockSource.Stop()
  122. for {
  123. select {
  124. case <-ctx.Done():
  125. return
  126. case <-clockSource.C:
  127. r.renderHostmaps("clock tick")
  128. r.renderFlow()
  129. }
  130. }
  131. }()
  132. return r
  133. }
  134. // AddRoute will place the nebula controller at the ip and port specified.
  135. // It does not look at the addr attached to the instance.
  136. // If a route is used, this will behave like a NAT for the return path.
  137. // Rewriting the source ip:port to what was last sent to from the origin
  138. func (r *R) AddRoute(ip netip.Addr, port uint16, c *nebula.Control) {
  139. r.Lock()
  140. defer r.Unlock()
  141. inAddr := netip.AddrPortFrom(ip, port)
  142. if _, ok := r.inNat[inAddr]; ok {
  143. panic("Duplicate listen address inNat: " + inAddr.String())
  144. }
  145. r.inNat[inAddr] = c
  146. }
  147. // RenderFlow renders the packet flow seen up until now and stops further automatic renders from happening.
  148. func (r *R) RenderFlow() {
  149. r.cancelRender()
  150. r.renderFlow()
  151. }
  152. // CancelFlowLogs stops flow logs from being tracked and destroys any logs already collected
  153. func (r *R) CancelFlowLogs() {
  154. r.cancelRender()
  155. r.flow = nil
  156. }
  157. func (r *R) renderFlow() {
  158. if r.flow == nil {
  159. return
  160. }
  161. f, err := os.OpenFile(r.fn, os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0644)
  162. if err != nil {
  163. panic(err)
  164. }
  165. var participants = map[netip.AddrPort]struct{}{}
  166. var participantsVals []string
  167. fmt.Fprintln(f, "```mermaid")
  168. fmt.Fprintln(f, "sequenceDiagram")
  169. // Assemble participants
  170. for _, e := range r.flow {
  171. if e.packet == nil {
  172. continue
  173. }
  174. addr := e.packet.from.GetUDPAddr()
  175. if _, ok := participants[addr]; ok {
  176. continue
  177. }
  178. participants[addr] = struct{}{}
  179. sanAddr := normalizeName(addr.String())
  180. participantsVals = append(participantsVals, sanAddr)
  181. fmt.Fprintf(
  182. f, " participant %s as Nebula: %s<br/>UDP: %s\n",
  183. sanAddr, e.packet.from.GetVpnAddrs(), sanAddr,
  184. )
  185. }
  186. if len(participantsVals) > 2 {
  187. // Get the first and last participantVals for notes
  188. participantsVals = []string{participantsVals[0], participantsVals[len(participantsVals)-1]}
  189. }
  190. // Print packets
  191. h := &header.H{}
  192. for _, e := range r.flow {
  193. if e.packet == nil {
  194. //fmt.Fprintf(f, " note over %s: %s\n", strings.Join(participantsVals, ", "), e.note)
  195. continue
  196. }
  197. p := e.packet
  198. if p.tun {
  199. fmt.Fprintln(f, r.formatUdpPacket(p))
  200. } else {
  201. if err := h.Parse(p.packet.Data); err != nil {
  202. panic(err)
  203. }
  204. line := "--x"
  205. if p.rx {
  206. line = "->>"
  207. }
  208. fmt.Fprintf(f,
  209. " %s%s%s: %s(%s), index %v, counter: %v\n",
  210. normalizeName(p.from.GetUDPAddr().String()),
  211. line,
  212. normalizeName(p.to.GetUDPAddr().String()),
  213. h.TypeName(), h.SubTypeName(), h.RemoteIndex, h.MessageCounter,
  214. )
  215. }
  216. }
  217. fmt.Fprintln(f, "```")
  218. for _, g := range r.additionalGraphs {
  219. fmt.Fprintf(f, "## %s\n", g.title)
  220. fmt.Fprintln(f, "```mermaid")
  221. fmt.Fprintln(f, g.content)
  222. fmt.Fprintln(f, "```")
  223. }
  224. }
  225. func normalizeName(s string) string {
  226. rx := regexp.MustCompile("[\\[\\]\\:]")
  227. return rx.ReplaceAllLiteralString(s, "_")
  228. }
  229. // IgnoreFlow tells the router to stop recording future flows that matches the provided criteria.
  230. // messageType and subType will target nebula underlay packets while tun will target nebula overlay packets
  231. // NOTE: This is a very broad system, if you set tun to true then no more tun traffic will be rendered
  232. func (r *R) IgnoreFlow(messageType header.MessageType, subType header.MessageSubType, tun NullBool) {
  233. r.Lock()
  234. defer r.Unlock()
  235. r.ignoreFlows = append(r.ignoreFlows, ignoreFlow{
  236. tun,
  237. messageType,
  238. subType,
  239. })
  240. }
  241. func (r *R) RenderHostmaps(title string, controls ...*nebula.Control) {
  242. r.Lock()
  243. defer r.Unlock()
  244. s := renderHostmaps(controls...)
  245. if len(r.additionalGraphs) > 0 {
  246. lastGraph := r.additionalGraphs[len(r.additionalGraphs)-1]
  247. if lastGraph.content == s && lastGraph.title == title {
  248. // Ignore this rendering if it matches the last rendering added
  249. // This is useful if you want to track rendering changes
  250. return
  251. }
  252. }
  253. r.additionalGraphs = append(r.additionalGraphs, mermaidGraph{
  254. title: title,
  255. content: s,
  256. })
  257. }
  258. func (r *R) renderHostmaps(title string) {
  259. c := maps.Values(r.controls)
  260. sort.SliceStable(c, func(i, j int) bool {
  261. return c[i].GetVpnAddrs()[0].Compare(c[j].GetVpnAddrs()[0]) > 0
  262. })
  263. s := renderHostmaps(c...)
  264. if len(r.additionalGraphs) > 0 {
  265. lastGraph := r.additionalGraphs[len(r.additionalGraphs)-1]
  266. if lastGraph.content == s {
  267. // Ignore this rendering if it matches the last rendering added
  268. // This is useful if you want to track rendering changes
  269. return
  270. }
  271. }
  272. r.additionalGraphs = append(r.additionalGraphs, mermaidGraph{
  273. title: title,
  274. content: s,
  275. })
  276. }
  277. // InjectFlow can be used to record packet flow if the test is handling the routing on its own.
  278. // The packet is assumed to have been received
  279. func (r *R) InjectFlow(from, to *nebula.Control, p *udp.Packet) {
  280. r.Lock()
  281. defer r.Unlock()
  282. r.unlockedInjectFlow(from, to, p, false)
  283. }
  284. func (r *R) Log(arg ...any) {
  285. if r.flow == nil {
  286. return
  287. }
  288. r.Lock()
  289. r.flow = append(r.flow, flowEntry{note: fmt.Sprint(arg...)})
  290. r.t.Log(arg...)
  291. r.Unlock()
  292. }
  293. func (r *R) Logf(format string, arg ...any) {
  294. if r.flow == nil {
  295. return
  296. }
  297. r.Lock()
  298. r.flow = append(r.flow, flowEntry{note: fmt.Sprintf(format, arg...)})
  299. r.t.Logf(format, arg...)
  300. r.Unlock()
  301. }
  302. // unlockedInjectFlow is used by the router to record a packet has been transmitted, the packet is returned and
  303. // should be marked as received AFTER it has been placed on the receivers channel.
  304. // If flow logs have been disabled this function will return nil
  305. func (r *R) unlockedInjectFlow(from, to *nebula.Control, p *udp.Packet, tun bool) *packet {
  306. if r.flow == nil {
  307. return nil
  308. }
  309. r.renderHostmaps(fmt.Sprintf("Packet %v", len(r.flow)))
  310. if len(r.ignoreFlows) > 0 {
  311. var h header.H
  312. err := h.Parse(p.Data)
  313. if err != nil {
  314. panic(err)
  315. }
  316. for _, i := range r.ignoreFlows {
  317. if !tun {
  318. if i.messageType == h.Type && i.subType == h.Subtype {
  319. return nil
  320. }
  321. } else if i.tun.HasValue && i.tun.IsTrue {
  322. return nil
  323. }
  324. }
  325. }
  326. fp := &packet{
  327. from: from,
  328. to: to,
  329. packet: p.Copy(),
  330. tun: tun,
  331. }
  332. r.flow = append(r.flow, flowEntry{packet: fp})
  333. return fp
  334. }
  335. // OnceFrom will route a single packet from sender then return
  336. // If the router doesn't have the nebula controller for that address, we panic
  337. func (r *R) OnceFrom(sender *nebula.Control) {
  338. r.RouteExitFunc(sender, func(*udp.Packet, *nebula.Control) ExitType {
  339. return RouteAndExit
  340. })
  341. }
  342. // RouteUntilTxTun will route for sender and return when a packet is seen on receivers tun
  343. // If the router doesn't have the nebula controller for that address, we panic
  344. func (r *R) RouteUntilTxTun(sender *nebula.Control, receiver *nebula.Control) []byte {
  345. tunTx := receiver.GetTunTxChan()
  346. udpTx := sender.GetUDPTxChan()
  347. for {
  348. select {
  349. // Maybe we already have something on the tun for us
  350. case b := <-tunTx:
  351. r.Lock()
  352. np := udp.Packet{Data: make([]byte, len(b))}
  353. copy(np.Data, b)
  354. r.unlockedInjectFlow(receiver, receiver, &np, true)
  355. r.Unlock()
  356. return b
  357. // Nope, lets push the sender along
  358. case p := <-udpTx:
  359. r.Lock()
  360. a := sender.GetUDPAddr()
  361. c := r.getControl(a, p.To, p)
  362. if c == nil {
  363. r.Unlock()
  364. panic("No control for udp tx " + a.String())
  365. }
  366. fp := r.unlockedInjectFlow(sender, c, p, false)
  367. c.InjectUDPPacket(p)
  368. fp.WasReceived()
  369. r.Unlock()
  370. }
  371. }
  372. }
  373. // RouteForAllUntilTxTun will route for everyone and return when a packet is seen on receivers tun
  374. // If the router doesn't have the nebula controller for that address, we panic
  375. func (r *R) RouteForAllUntilTxTun(receiver *nebula.Control) []byte {
  376. sc := make([]reflect.SelectCase, len(r.controls)+1)
  377. cm := make([]*nebula.Control, len(r.controls)+1)
  378. i := 0
  379. sc[i] = reflect.SelectCase{
  380. Dir: reflect.SelectRecv,
  381. Chan: reflect.ValueOf(receiver.GetTunTxChan()),
  382. Send: reflect.Value{},
  383. }
  384. cm[i] = receiver
  385. i++
  386. for _, c := range r.controls {
  387. sc[i] = reflect.SelectCase{
  388. Dir: reflect.SelectRecv,
  389. Chan: reflect.ValueOf(c.GetUDPTxChan()),
  390. Send: reflect.Value{},
  391. }
  392. cm[i] = c
  393. i++
  394. }
  395. for {
  396. x, rx, _ := reflect.Select(sc)
  397. r.Lock()
  398. if x == 0 {
  399. // we are the tun tx, we can exit
  400. p := rx.Interface().([]byte)
  401. np := udp.Packet{Data: make([]byte, len(p))}
  402. copy(np.Data, p)
  403. r.unlockedInjectFlow(cm[x], cm[x], &np, true)
  404. r.Unlock()
  405. return p
  406. } else {
  407. // we are a udp tx, route and continue
  408. p := rx.Interface().(*udp.Packet)
  409. a := cm[x].GetUDPAddr()
  410. c := r.getControl(a, p.To, p)
  411. if c == nil {
  412. r.Unlock()
  413. panic(fmt.Sprintf("No control for udp tx %s", p.To))
  414. }
  415. fp := r.unlockedInjectFlow(cm[x], c, p, false)
  416. c.InjectUDPPacket(p)
  417. fp.WasReceived()
  418. }
  419. r.Unlock()
  420. }
  421. }
  422. // RouteExitFunc will call the whatDo func with each udp packet from sender.
  423. // whatDo can return:
  424. // - exitNow: the packet will not be routed and this call will return immediately
  425. // - routeAndExit: this call will return immediately after routing the last packet from sender
  426. // - keepRouting: the packet will be routed and whatDo will be called again on the next packet from sender
  427. func (r *R) RouteExitFunc(sender *nebula.Control, whatDo ExitFunc) {
  428. h := &header.H{}
  429. for {
  430. p := sender.GetFromUDP(true)
  431. r.Lock()
  432. if err := h.Parse(p.Data); err != nil {
  433. panic(err)
  434. }
  435. receiver := r.getControl(sender.GetUDPAddr(), p.To, p)
  436. if receiver == nil {
  437. r.Unlock()
  438. panic("Can't RouteExitFunc for host: " + p.To.String())
  439. }
  440. e := whatDo(p, receiver)
  441. switch e {
  442. case ExitNow:
  443. r.Unlock()
  444. return
  445. case RouteAndExit:
  446. fp := r.unlockedInjectFlow(sender, receiver, p, false)
  447. receiver.InjectUDPPacket(p)
  448. fp.WasReceived()
  449. r.Unlock()
  450. return
  451. case KeepRouting:
  452. fp := r.unlockedInjectFlow(sender, receiver, p, false)
  453. receiver.InjectUDPPacket(p)
  454. fp.WasReceived()
  455. default:
  456. panic(fmt.Sprintf("Unknown exitFunc return: %v", e))
  457. }
  458. r.Unlock()
  459. }
  460. }
  461. // RouteUntilAfterMsgType will route for sender until a message type is seen and sent from sender
  462. // If the router doesn't have the nebula controller for that address, we panic
  463. func (r *R) RouteUntilAfterMsgType(sender *nebula.Control, msgType header.MessageType, subType header.MessageSubType) {
  464. h := &header.H{}
  465. r.RouteExitFunc(sender, func(p *udp.Packet, r *nebula.Control) ExitType {
  466. if err := h.Parse(p.Data); err != nil {
  467. panic(err)
  468. }
  469. if h.Type == msgType && h.Subtype == subType {
  470. return RouteAndExit
  471. }
  472. return KeepRouting
  473. })
  474. }
  475. func (r *R) RouteForAllUntilAfterMsgTypeTo(receiver *nebula.Control, msgType header.MessageType, subType header.MessageSubType) {
  476. h := &header.H{}
  477. r.RouteForAllExitFunc(func(p *udp.Packet, r *nebula.Control) ExitType {
  478. if r != receiver {
  479. return KeepRouting
  480. }
  481. if err := h.Parse(p.Data); err != nil {
  482. panic(err)
  483. }
  484. if h.Type == msgType && h.Subtype == subType {
  485. return RouteAndExit
  486. }
  487. return KeepRouting
  488. })
  489. }
  490. func (r *R) InjectUDPPacket(sender, receiver *nebula.Control, packet *udp.Packet) {
  491. r.Lock()
  492. defer r.Unlock()
  493. fp := r.unlockedInjectFlow(sender, receiver, packet, false)
  494. receiver.InjectUDPPacket(packet)
  495. fp.WasReceived()
  496. }
  497. // RouteForUntilAfterToAddr will route for sender and return only after it sees and sends a packet destined for toAddr
  498. // finish can be any of the exitType values except `keepRouting`, the default value is `routeAndExit`
  499. // If the router doesn't have the nebula controller for that address, we panic
  500. func (r *R) RouteForUntilAfterToAddr(sender *nebula.Control, toAddr netip.AddrPort, finish ExitType) {
  501. if finish == KeepRouting {
  502. finish = RouteAndExit
  503. }
  504. r.RouteExitFunc(sender, func(p *udp.Packet, r *nebula.Control) ExitType {
  505. if p.To == toAddr {
  506. return finish
  507. }
  508. return KeepRouting
  509. })
  510. }
  511. // RouteForAllExitFunc will route for every registered controller and calls the whatDo func with each udp packet from
  512. // whatDo can return:
  513. // - exitNow: the packet will not be routed and this call will return immediately
  514. // - routeAndExit: this call will return immediately after routing the last packet from sender
  515. // - keepRouting: the packet will be routed and whatDo will be called again on the next packet from sender
  516. func (r *R) RouteForAllExitFunc(whatDo ExitFunc) {
  517. sc := make([]reflect.SelectCase, len(r.controls))
  518. cm := make([]*nebula.Control, len(r.controls))
  519. i := 0
  520. for _, c := range r.controls {
  521. sc[i] = reflect.SelectCase{
  522. Dir: reflect.SelectRecv,
  523. Chan: reflect.ValueOf(c.GetUDPTxChan()),
  524. Send: reflect.Value{},
  525. }
  526. cm[i] = c
  527. i++
  528. }
  529. for {
  530. x, rx, _ := reflect.Select(sc)
  531. r.Lock()
  532. p := rx.Interface().(*udp.Packet)
  533. receiver := r.getControl(cm[x].GetUDPAddr(), p.To, p)
  534. if receiver == nil {
  535. r.Unlock()
  536. panic("Can't RouteForAllExitFunc for host: " + p.To.String())
  537. }
  538. e := whatDo(p, receiver)
  539. switch e {
  540. case ExitNow:
  541. r.Unlock()
  542. return
  543. case RouteAndExit:
  544. fp := r.unlockedInjectFlow(cm[x], receiver, p, false)
  545. receiver.InjectUDPPacket(p)
  546. fp.WasReceived()
  547. r.Unlock()
  548. return
  549. case KeepRouting:
  550. fp := r.unlockedInjectFlow(cm[x], receiver, p, false)
  551. receiver.InjectUDPPacket(p)
  552. fp.WasReceived()
  553. default:
  554. panic(fmt.Sprintf("Unknown exitFunc return: %v", e))
  555. }
  556. r.Unlock()
  557. }
  558. }
  559. // FlushAll will route for every registered controller, exiting once there are no packets left to route
  560. func (r *R) FlushAll() {
  561. sc := make([]reflect.SelectCase, len(r.controls))
  562. cm := make([]*nebula.Control, len(r.controls))
  563. i := 0
  564. for _, c := range r.controls {
  565. sc[i] = reflect.SelectCase{
  566. Dir: reflect.SelectRecv,
  567. Chan: reflect.ValueOf(c.GetUDPTxChan()),
  568. Send: reflect.Value{},
  569. }
  570. cm[i] = c
  571. i++
  572. }
  573. // Add a default case to exit when nothing is left to send
  574. sc = append(sc, reflect.SelectCase{
  575. Dir: reflect.SelectDefault,
  576. Chan: reflect.Value{},
  577. Send: reflect.Value{},
  578. })
  579. for {
  580. x, rx, ok := reflect.Select(sc)
  581. if !ok {
  582. return
  583. }
  584. r.Lock()
  585. p := rx.Interface().(*udp.Packet)
  586. receiver := r.getControl(cm[x].GetUDPAddr(), p.To, p)
  587. if receiver == nil {
  588. r.Unlock()
  589. panic("Can't FlushAll for host: " + p.To.String())
  590. }
  591. r.Unlock()
  592. }
  593. }
  594. // getControl performs or seeds NAT translation and returns the control for toAddr, p from fields may change
  595. // This is an internal router function, the caller must hold the lock
  596. func (r *R) getControl(fromAddr, toAddr netip.AddrPort, p *udp.Packet) *nebula.Control {
  597. if newAddr, ok := r.outNat[fromAddr.String()+":"+toAddr.String()]; ok {
  598. p.From = newAddr
  599. }
  600. c, ok := r.inNat[toAddr]
  601. if ok {
  602. r.outNat[c.GetUDPAddr().String()+":"+fromAddr.String()] = toAddr
  603. return c
  604. }
  605. return r.controls[toAddr]
  606. }
  607. func (r *R) formatUdpPacket(p *packet) string {
  608. var packet gopacket.Packet
  609. var srcAddr netip.Addr
  610. packet = gopacket.NewPacket(p.packet.Data, layers.LayerTypeIPv6, gopacket.Lazy)
  611. if packet.ErrorLayer() == nil {
  612. v6 := packet.Layer(layers.LayerTypeIPv6).(*layers.IPv6)
  613. if v6 == nil {
  614. panic("not an ipv6 packet")
  615. }
  616. srcAddr, _ = netip.AddrFromSlice(v6.SrcIP)
  617. } else {
  618. packet = gopacket.NewPacket(p.packet.Data, layers.LayerTypeIPv4, gopacket.Lazy)
  619. v6 := packet.Layer(layers.LayerTypeIPv4).(*layers.IPv4)
  620. if v6 == nil {
  621. panic("not an ipv6 packet")
  622. }
  623. srcAddr, _ = netip.AddrFromSlice(v6.SrcIP)
  624. }
  625. from := "unknown"
  626. if c, ok := r.vpnControls[srcAddr]; ok {
  627. from = c.GetUDPAddr().String()
  628. }
  629. udpLayer := packet.Layer(layers.LayerTypeUDP).(*layers.UDP)
  630. if udpLayer == nil {
  631. panic("not a udp packet")
  632. }
  633. data := packet.ApplicationLayer()
  634. return fmt.Sprintf(
  635. " %s-->>%s: src port: %v<br/>dest port: %v<br/>data: \"%v\"\n",
  636. normalizeName(from),
  637. normalizeName(p.to.GetUDPAddr().String()),
  638. udpLayer.SrcPort,
  639. udpLayer.DstPort,
  640. string(data.Payload()),
  641. )
  642. }