lighthouse_test.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. package nebula
  2. import (
  3. "context"
  4. "encoding/binary"
  5. "fmt"
  6. "net/netip"
  7. "testing"
  8. "github.com/gaissmai/bart"
  9. "github.com/slackhq/nebula/cert"
  10. "github.com/slackhq/nebula/config"
  11. "github.com/slackhq/nebula/header"
  12. "github.com/slackhq/nebula/test"
  13. "github.com/stretchr/testify/assert"
  14. "gopkg.in/yaml.v2"
  15. )
  16. //TODO: Add a test to ensure udpAddr is copied and not reused
  17. func TestOldIPv4Only(t *testing.T) {
  18. // This test ensures our new ipv6 enabled LH protobuf IpAndPorts works with the old style to enable backwards compatibility
  19. b := []byte{8, 129, 130, 132, 80, 16, 10}
  20. var m V4AddrPort
  21. err := m.Unmarshal(b)
  22. assert.NoError(t, err)
  23. ip := netip.MustParseAddr("10.1.1.1")
  24. bp := ip.As4()
  25. assert.Equal(t, binary.BigEndian.Uint32(bp[:]), m.GetAddr())
  26. }
  27. func Test_lhStaticMapping(t *testing.T) {
  28. l := test.NewLogger()
  29. myVpnNet := netip.MustParsePrefix("10.128.0.1/16")
  30. nt := new(bart.Table[struct{}])
  31. nt.Insert(myVpnNet, struct{}{})
  32. cs := &CertState{
  33. myVpnNetworks: []netip.Prefix{myVpnNet},
  34. myVpnNetworksTable: nt,
  35. }
  36. lh1 := "10.128.0.2"
  37. c := config.NewC(l)
  38. c.Settings["lighthouse"] = map[interface{}]interface{}{"hosts": []interface{}{lh1}}
  39. c.Settings["static_host_map"] = map[interface{}]interface{}{lh1: []interface{}{"1.1.1.1:4242"}}
  40. _, err := NewLightHouseFromConfig(context.Background(), l, c, cs, nil, nil)
  41. assert.Nil(t, err)
  42. lh2 := "10.128.0.3"
  43. c = config.NewC(l)
  44. c.Settings["lighthouse"] = map[interface{}]interface{}{"hosts": []interface{}{lh1, lh2}}
  45. c.Settings["static_host_map"] = map[interface{}]interface{}{lh1: []interface{}{"100.1.1.1:4242"}}
  46. _, err = NewLightHouseFromConfig(context.Background(), l, c, cs, nil, nil)
  47. assert.EqualError(t, err, "lighthouse 10.128.0.3 does not have a static_host_map entry")
  48. }
  49. func TestReloadLighthouseInterval(t *testing.T) {
  50. l := test.NewLogger()
  51. myVpnNet := netip.MustParsePrefix("10.128.0.1/16")
  52. nt := new(bart.Table[struct{}])
  53. nt.Insert(myVpnNet, struct{}{})
  54. cs := &CertState{
  55. myVpnNetworks: []netip.Prefix{myVpnNet},
  56. myVpnNetworksTable: nt,
  57. }
  58. lh1 := "10.128.0.2"
  59. c := config.NewC(l)
  60. c.Settings["lighthouse"] = map[interface{}]interface{}{
  61. "hosts": []interface{}{lh1},
  62. "interval": "1s",
  63. }
  64. c.Settings["static_host_map"] = map[interface{}]interface{}{lh1: []interface{}{"1.1.1.1:4242"}}
  65. lh, err := NewLightHouseFromConfig(context.Background(), l, c, cs, nil, nil)
  66. assert.NoError(t, err)
  67. lh.ifce = &mockEncWriter{}
  68. // The first one routine is kicked off by main.go currently, lets make sure that one dies
  69. assert.NoError(t, c.ReloadConfigString("lighthouse:\n interval: 5"))
  70. assert.Equal(t, int64(5), lh.interval.Load())
  71. // Subsequent calls are killed off by the LightHouse.Reload function
  72. assert.NoError(t, c.ReloadConfigString("lighthouse:\n interval: 10"))
  73. assert.Equal(t, int64(10), lh.interval.Load())
  74. // If this completes then nothing is stealing our reload routine
  75. assert.NoError(t, c.ReloadConfigString("lighthouse:\n interval: 11"))
  76. assert.Equal(t, int64(11), lh.interval.Load())
  77. }
  78. func BenchmarkLighthouseHandleRequest(b *testing.B) {
  79. l := test.NewLogger()
  80. myVpnNet := netip.MustParsePrefix("10.128.0.1/0")
  81. nt := new(bart.Table[struct{}])
  82. nt.Insert(myVpnNet, struct{}{})
  83. cs := &CertState{
  84. myVpnNetworks: []netip.Prefix{myVpnNet},
  85. myVpnNetworksTable: nt,
  86. }
  87. c := config.NewC(l)
  88. lh, err := NewLightHouseFromConfig(context.Background(), l, c, cs, nil, nil)
  89. if !assert.NoError(b, err) {
  90. b.Fatal()
  91. }
  92. hAddr := netip.MustParseAddrPort("4.5.6.7:12345")
  93. hAddr2 := netip.MustParseAddrPort("4.5.6.7:12346")
  94. vpnIp3 := netip.MustParseAddr("0.0.0.3")
  95. lh.addrMap[vpnIp3] = NewRemoteList([]netip.Addr{vpnIp3}, nil)
  96. lh.addrMap[vpnIp3].unlockedSetV4(
  97. vpnIp3,
  98. vpnIp3,
  99. []*V4AddrPort{
  100. netAddrToProtoV4AddrPort(hAddr.Addr(), hAddr.Port()),
  101. netAddrToProtoV4AddrPort(hAddr2.Addr(), hAddr2.Port()),
  102. },
  103. func(netip.Addr, *V4AddrPort) bool { return true },
  104. )
  105. rAddr := netip.MustParseAddrPort("1.2.2.3:12345")
  106. rAddr2 := netip.MustParseAddrPort("1.2.2.3:12346")
  107. vpnIp2 := netip.MustParseAddr("0.0.0.3")
  108. lh.addrMap[vpnIp2] = NewRemoteList([]netip.Addr{vpnIp2}, nil)
  109. lh.addrMap[vpnIp2].unlockedSetV4(
  110. vpnIp3,
  111. vpnIp3,
  112. []*V4AddrPort{
  113. netAddrToProtoV4AddrPort(rAddr.Addr(), rAddr.Port()),
  114. netAddrToProtoV4AddrPort(rAddr2.Addr(), rAddr2.Port()),
  115. },
  116. func(netip.Addr, *V4AddrPort) bool { return true },
  117. )
  118. mw := &mockEncWriter{}
  119. hi := []netip.Addr{vpnIp2}
  120. b.Run("notfound", func(b *testing.B) {
  121. lhh := lh.NewRequestHandler()
  122. req := &NebulaMeta{
  123. Type: NebulaMeta_HostQuery,
  124. Details: &NebulaMetaDetails{
  125. OldVpnAddr: 4,
  126. V4AddrPorts: nil,
  127. },
  128. }
  129. p, err := req.Marshal()
  130. assert.NoError(b, err)
  131. for n := 0; n < b.N; n++ {
  132. lhh.HandleRequest(rAddr, hi, p, mw)
  133. }
  134. })
  135. b.Run("found", func(b *testing.B) {
  136. lhh := lh.NewRequestHandler()
  137. req := &NebulaMeta{
  138. Type: NebulaMeta_HostQuery,
  139. Details: &NebulaMetaDetails{
  140. OldVpnAddr: 3,
  141. V4AddrPorts: nil,
  142. },
  143. }
  144. p, err := req.Marshal()
  145. assert.NoError(b, err)
  146. for n := 0; n < b.N; n++ {
  147. lhh.HandleRequest(rAddr, hi, p, mw)
  148. }
  149. })
  150. }
  151. func TestLighthouse_Memory(t *testing.T) {
  152. l := test.NewLogger()
  153. myUdpAddr0 := netip.MustParseAddrPort("10.0.0.2:4242")
  154. myUdpAddr1 := netip.MustParseAddrPort("192.168.0.2:4242")
  155. myUdpAddr2 := netip.MustParseAddrPort("172.16.0.2:4242")
  156. myUdpAddr3 := netip.MustParseAddrPort("100.152.0.2:4242")
  157. myUdpAddr4 := netip.MustParseAddrPort("24.15.0.2:4242")
  158. myUdpAddr5 := netip.MustParseAddrPort("192.168.0.2:4243")
  159. myUdpAddr6 := netip.MustParseAddrPort("192.168.0.2:4244")
  160. myUdpAddr7 := netip.MustParseAddrPort("192.168.0.2:4245")
  161. myUdpAddr8 := netip.MustParseAddrPort("192.168.0.2:4246")
  162. myUdpAddr9 := netip.MustParseAddrPort("192.168.0.2:4247")
  163. myUdpAddr10 := netip.MustParseAddrPort("192.168.0.2:4248")
  164. myUdpAddr11 := netip.MustParseAddrPort("192.168.0.2:4249")
  165. myVpnIp := netip.MustParseAddr("10.128.0.2")
  166. theirUdpAddr0 := netip.MustParseAddrPort("10.0.0.3:4242")
  167. theirUdpAddr1 := netip.MustParseAddrPort("192.168.0.3:4242")
  168. theirUdpAddr2 := netip.MustParseAddrPort("172.16.0.3:4242")
  169. theirUdpAddr3 := netip.MustParseAddrPort("100.152.0.3:4242")
  170. theirUdpAddr4 := netip.MustParseAddrPort("24.15.0.3:4242")
  171. theirVpnIp := netip.MustParseAddr("10.128.0.3")
  172. c := config.NewC(l)
  173. c.Settings["lighthouse"] = map[interface{}]interface{}{"am_lighthouse": true}
  174. c.Settings["listen"] = map[interface{}]interface{}{"port": 4242}
  175. myVpnNet := netip.MustParsePrefix("10.128.0.1/24")
  176. nt := new(bart.Table[struct{}])
  177. nt.Insert(myVpnNet, struct{}{})
  178. cs := &CertState{
  179. myVpnNetworks: []netip.Prefix{myVpnNet},
  180. myVpnNetworksTable: nt,
  181. }
  182. lh, err := NewLightHouseFromConfig(context.Background(), l, c, cs, nil, nil)
  183. lh.ifce = &mockEncWriter{}
  184. assert.NoError(t, err)
  185. lhh := lh.NewRequestHandler()
  186. // Test that my first update responds with just that
  187. newLHHostUpdate(myUdpAddr0, myVpnIp, []netip.AddrPort{myUdpAddr1, myUdpAddr2}, lhh)
  188. r := newLHHostRequest(myUdpAddr0, myVpnIp, myVpnIp, lhh)
  189. assertIp4InArray(t, r.msg.Details.V4AddrPorts, myUdpAddr1, myUdpAddr2)
  190. // Ensure we don't accumulate addresses
  191. newLHHostUpdate(myUdpAddr0, myVpnIp, []netip.AddrPort{myUdpAddr3}, lhh)
  192. r = newLHHostRequest(myUdpAddr0, myVpnIp, myVpnIp, lhh)
  193. assertIp4InArray(t, r.msg.Details.V4AddrPorts, myUdpAddr3)
  194. // Grow it back to 2
  195. newLHHostUpdate(myUdpAddr0, myVpnIp, []netip.AddrPort{myUdpAddr1, myUdpAddr4}, lhh)
  196. r = newLHHostRequest(myUdpAddr0, myVpnIp, myVpnIp, lhh)
  197. assertIp4InArray(t, r.msg.Details.V4AddrPorts, myUdpAddr1, myUdpAddr4)
  198. // Update a different host and ask about it
  199. newLHHostUpdate(theirUdpAddr0, theirVpnIp, []netip.AddrPort{theirUdpAddr1, theirUdpAddr2, theirUdpAddr3, theirUdpAddr4}, lhh)
  200. r = newLHHostRequest(theirUdpAddr0, theirVpnIp, theirVpnIp, lhh)
  201. assertIp4InArray(t, r.msg.Details.V4AddrPorts, theirUdpAddr1, theirUdpAddr2, theirUdpAddr3, theirUdpAddr4)
  202. // Have both hosts ask about the other
  203. r = newLHHostRequest(theirUdpAddr0, theirVpnIp, myVpnIp, lhh)
  204. assertIp4InArray(t, r.msg.Details.V4AddrPorts, myUdpAddr1, myUdpAddr4)
  205. r = newLHHostRequest(myUdpAddr0, myVpnIp, theirVpnIp, lhh)
  206. assertIp4InArray(t, r.msg.Details.V4AddrPorts, theirUdpAddr1, theirUdpAddr2, theirUdpAddr3, theirUdpAddr4)
  207. // Make sure we didn't get changed
  208. r = newLHHostRequest(myUdpAddr0, myVpnIp, myVpnIp, lhh)
  209. assertIp4InArray(t, r.msg.Details.V4AddrPorts, myUdpAddr1, myUdpAddr4)
  210. // Ensure proper ordering and limiting
  211. // Send 12 addrs, get 10 back, the last 2 removed, allowing the duplicate to remain (clients dedupe)
  212. newLHHostUpdate(
  213. myUdpAddr0,
  214. myVpnIp,
  215. []netip.AddrPort{
  216. myUdpAddr1,
  217. myUdpAddr2,
  218. myUdpAddr3,
  219. myUdpAddr4,
  220. myUdpAddr5,
  221. myUdpAddr5, //Duplicated on purpose
  222. myUdpAddr6,
  223. myUdpAddr7,
  224. myUdpAddr8,
  225. myUdpAddr9,
  226. myUdpAddr10,
  227. myUdpAddr11, // This should get cut
  228. }, lhh)
  229. r = newLHHostRequest(myUdpAddr0, myVpnIp, myVpnIp, lhh)
  230. assertIp4InArray(
  231. t,
  232. r.msg.Details.V4AddrPorts,
  233. myUdpAddr1, myUdpAddr2, myUdpAddr3, myUdpAddr4, myUdpAddr5, myUdpAddr5, myUdpAddr6, myUdpAddr7, myUdpAddr8, myUdpAddr9,
  234. )
  235. // Make sure we won't add ips in our vpn network
  236. bad1 := netip.MustParseAddrPort("10.128.0.99:4242")
  237. bad2 := netip.MustParseAddrPort("10.128.0.100:4242")
  238. good := netip.MustParseAddrPort("1.128.0.99:4242")
  239. newLHHostUpdate(myUdpAddr0, myVpnIp, []netip.AddrPort{bad1, bad2, good}, lhh)
  240. r = newLHHostRequest(myUdpAddr0, myVpnIp, myVpnIp, lhh)
  241. assertIp4InArray(t, r.msg.Details.V4AddrPorts, good)
  242. }
  243. func TestLighthouse_reload(t *testing.T) {
  244. l := test.NewLogger()
  245. c := config.NewC(l)
  246. c.Settings["lighthouse"] = map[interface{}]interface{}{"am_lighthouse": true}
  247. c.Settings["listen"] = map[interface{}]interface{}{"port": 4242}
  248. myVpnNet := netip.MustParsePrefix("10.128.0.1/24")
  249. nt := new(bart.Table[struct{}])
  250. nt.Insert(myVpnNet, struct{}{})
  251. cs := &CertState{
  252. myVpnNetworks: []netip.Prefix{myVpnNet},
  253. myVpnNetworksTable: nt,
  254. }
  255. lh, err := NewLightHouseFromConfig(context.Background(), l, c, cs, nil, nil)
  256. assert.NoError(t, err)
  257. nc := map[interface{}]interface{}{
  258. "static_host_map": map[interface{}]interface{}{
  259. "10.128.0.2": []interface{}{"1.1.1.1:4242"},
  260. },
  261. }
  262. rc, err := yaml.Marshal(nc)
  263. assert.NoError(t, err)
  264. c.ReloadConfigString(string(rc))
  265. err = lh.reload(c, false)
  266. assert.NoError(t, err)
  267. }
  268. func newLHHostRequest(fromAddr netip.AddrPort, myVpnIp, queryVpnIp netip.Addr, lhh *LightHouseHandler) testLhReply {
  269. //TODO: IPV6-WORK
  270. bip := queryVpnIp.As4()
  271. req := &NebulaMeta{
  272. Type: NebulaMeta_HostQuery,
  273. Details: &NebulaMetaDetails{
  274. OldVpnAddr: binary.BigEndian.Uint32(bip[:]),
  275. },
  276. }
  277. b, err := req.Marshal()
  278. if err != nil {
  279. panic(err)
  280. }
  281. filter := NebulaMeta_HostQueryReply
  282. w := &testEncWriter{
  283. metaFilter: &filter,
  284. }
  285. lhh.HandleRequest(fromAddr, []netip.Addr{myVpnIp}, b, w)
  286. return w.lastReply
  287. }
  288. func newLHHostUpdate(fromAddr netip.AddrPort, vpnIp netip.Addr, addrs []netip.AddrPort, lhh *LightHouseHandler) {
  289. //TODO: IPV6-WORK
  290. bip := vpnIp.As4()
  291. req := &NebulaMeta{
  292. Type: NebulaMeta_HostUpdateNotification,
  293. Details: &NebulaMetaDetails{
  294. OldVpnAddr: binary.BigEndian.Uint32(bip[:]),
  295. V4AddrPorts: make([]*V4AddrPort, len(addrs)),
  296. },
  297. }
  298. for k, v := range addrs {
  299. req.Details.V4AddrPorts[k] = netAddrToProtoV4AddrPort(v.Addr(), v.Port())
  300. }
  301. b, err := req.Marshal()
  302. if err != nil {
  303. panic(err)
  304. }
  305. w := &testEncWriter{}
  306. lhh.HandleRequest(fromAddr, []netip.Addr{vpnIp}, b, w)
  307. }
  308. //TODO: this is a RemoteList test
  309. //func Test_lhRemoteAllowList(t *testing.T) {
  310. // l := NewLogger()
  311. // c := NewConfig(l)
  312. // c.Settings["remoteallowlist"] = map[interface{}]interface{}{
  313. // "10.20.0.0/12": false,
  314. // }
  315. // allowList, err := c.GetAllowList("remoteallowlist", false)
  316. // assert.Nil(t, err)
  317. //
  318. // lh1 := "10.128.0.2"
  319. // lh1IP := net.ParseIP(lh1)
  320. //
  321. // udpServer, _ := NewListener(l, "0.0.0.0", 0, true)
  322. //
  323. // lh := NewLightHouse(l, true, &net.IPNet{IP: net.IP{0, 0, 0, 1}, Mask: net.IPMask{255, 255, 255, 0}}, []uint32{ip2int(lh1IP)}, 10, 10003, udpServer, false, 1, false)
  324. // lh.SetRemoteAllowList(allowList)
  325. //
  326. // // A disallowed ip should not enter the cache but we should end up with an empty entry in the addrMap
  327. // remote1IP := net.ParseIP("10.20.0.3")
  328. // remotes := lh.unlockedGetRemoteList(ip2int(remote1IP))
  329. // remotes.unlockedPrependV4(ip2int(remote1IP), NewIp4AndPort(remote1IP, 4242))
  330. // assert.NotNil(t, lh.addrMap[ip2int(remote1IP)])
  331. // assert.Empty(t, lh.addrMap[ip2int(remote1IP)].CopyAddrs([]*net.IPNet{}))
  332. //
  333. // // Make sure a good ip enters the cache and addrMap
  334. // remote2IP := net.ParseIP("10.128.0.3")
  335. // remote2UDPAddr := NewUDPAddr(remote2IP, uint16(4242))
  336. // lh.addRemoteV4(ip2int(remote2IP), ip2int(remote2IP), NewIp4AndPort(remote2UDPAddr.IP, uint32(remote2UDPAddr.Port)), false, false)
  337. // assertUdpAddrInArray(t, lh.addrMap[ip2int(remote2IP)].CopyAddrs([]*net.IPNet{}), remote2UDPAddr)
  338. //
  339. // // Another good ip gets into the cache, ordering is inverted
  340. // remote3IP := net.ParseIP("10.128.0.4")
  341. // remote3UDPAddr := NewUDPAddr(remote3IP, uint16(4243))
  342. // lh.addRemoteV4(ip2int(remote2IP), ip2int(remote2IP), NewIp4AndPort(remote3UDPAddr.IP, uint32(remote3UDPAddr.Port)), false, false)
  343. // assertUdpAddrInArray(t, lh.addrMap[ip2int(remote2IP)].CopyAddrs([]*net.IPNet{}), remote2UDPAddr, remote3UDPAddr)
  344. //
  345. // // If we exceed the length limit we should only have the most recent addresses
  346. // addedAddrs := []*udpAddr{}
  347. // for i := 0; i < 11; i++ {
  348. // remoteUDPAddr := NewUDPAddr(net.IP{10, 128, 0, 4}, uint16(4243+i))
  349. // lh.addRemoteV4(ip2int(remote2IP), ip2int(remote2IP), NewIp4AndPort(remoteUDPAddr.IP, uint32(remoteUDPAddr.Port)), false, false)
  350. // // The first entry here is a duplicate, don't add it to the assert list
  351. // if i != 0 {
  352. // addedAddrs = append(addedAddrs, remoteUDPAddr)
  353. // }
  354. // }
  355. //
  356. // // We should only have the last 10 of what we tried to add
  357. // assert.True(t, len(addedAddrs) >= 10, "We should have tried to add at least 10 addresses")
  358. // assertUdpAddrInArray(
  359. // t,
  360. // lh.addrMap[ip2int(remote2IP)].CopyAddrs([]*net.IPNet{}),
  361. // addedAddrs[0],
  362. // addedAddrs[1],
  363. // addedAddrs[2],
  364. // addedAddrs[3],
  365. // addedAddrs[4],
  366. // addedAddrs[5],
  367. // addedAddrs[6],
  368. // addedAddrs[7],
  369. // addedAddrs[8],
  370. // addedAddrs[9],
  371. // )
  372. //}
  373. type testLhReply struct {
  374. nebType header.MessageType
  375. nebSubType header.MessageSubType
  376. vpnIp netip.Addr
  377. msg *NebulaMeta
  378. }
  379. type testEncWriter struct {
  380. lastReply testLhReply
  381. metaFilter *NebulaMeta_MessageType
  382. protocolVersion cert.Version
  383. }
  384. func (tw *testEncWriter) SendVia(via *HostInfo, relay *Relay, ad, nb, out []byte, nocopy bool) {
  385. }
  386. func (tw *testEncWriter) Handshake(vpnIp netip.Addr) {
  387. }
  388. func (tw *testEncWriter) SendMessageToHostInfo(t header.MessageType, st header.MessageSubType, hostinfo *HostInfo, p, _, _ []byte) {
  389. msg := &NebulaMeta{}
  390. err := msg.Unmarshal(p)
  391. if tw.metaFilter == nil || msg.Type == *tw.metaFilter {
  392. tw.lastReply = testLhReply{
  393. nebType: t,
  394. nebSubType: st,
  395. vpnIp: hostinfo.vpnAddrs[0],
  396. msg: msg,
  397. }
  398. }
  399. if err != nil {
  400. panic(err)
  401. }
  402. }
  403. func (tw *testEncWriter) SendMessageToVpnAddr(t header.MessageType, st header.MessageSubType, vpnIp netip.Addr, p, _, _ []byte) {
  404. msg := &NebulaMeta{}
  405. err := msg.Unmarshal(p)
  406. if tw.metaFilter == nil || msg.Type == *tw.metaFilter {
  407. tw.lastReply = testLhReply{
  408. nebType: t,
  409. nebSubType: st,
  410. vpnIp: vpnIp,
  411. msg: msg,
  412. }
  413. }
  414. if err != nil {
  415. panic(err)
  416. }
  417. }
  418. func (tw *testEncWriter) GetHostInfo(vpnIp netip.Addr) *HostInfo {
  419. return nil
  420. }
  421. func (tw *testEncWriter) GetCertState() *CertState {
  422. return &CertState{defaultVersion: tw.protocolVersion}
  423. }
  424. // assertIp4InArray asserts every address in want is at the same position in have and that the lengths match
  425. func assertIp4InArray(t *testing.T, have []*V4AddrPort, want ...netip.AddrPort) {
  426. if !assert.Len(t, have, len(want)) {
  427. return
  428. }
  429. for k, w := range want {
  430. //TODO: IPV6-WORK
  431. h := protoV4AddrPortToNetAddrPort(have[k])
  432. if !(h == w) {
  433. assert.Fail(t, fmt.Sprintf("Response did not contain: %v at %v, found %v", w, k, h))
  434. }
  435. }
  436. }