@@ -287,9 +287,44 @@ func (s *state) _handleBootstrap(from, to *peer, rx *types.Frame) bool {
287287 }
288288 }
289289
290+ // Prepare the new routing table entry.
291+ s ._ordering ++
290292 index := virtualSnakeIndex {
291293 PublicKey : rx .DestinationKey ,
292294 }
295+ entry := & virtualSnakeEntry {
296+ virtualSnakeIndex : & index ,
297+ Source : from ,
298+ Destination : to ,
299+ LastSeen : time .Now (),
300+ Watermark : types.VirtualSnakeWatermark {
301+ PublicKey : index .PublicKey ,
302+ Sequence : bootstrap .Sequence ,
303+ },
304+ Ordering : s ._ordering ,
305+ }
306+
307+ // Update our entry for the highest public key we've seen via this peer.
308+ // If we haven't got an entry then we'll accept it as long as it's stronger
309+ // than our own key. If we have got an entry then we'll accept it if the
310+ // sequence number is higher or the key is stronger. If the chosen update
311+ // ends up being our best highest entry, we'll flood it to all of our peers.
312+ changed := false
313+ if highest , ok := s ._highest [from ]; ok && highest .valid () {
314+ diff := index .PublicKey .CompareTo (highest .PublicKey )
315+ switch {
316+ case diff > 0 :
317+ fallthrough
318+ case diff == 0 && bootstrap .Sequence > highest .Watermark .Sequence :
319+ s ._highest [from ] = entry
320+ changed = true
321+ }
322+ } else {
323+ if index .PublicKey .CompareTo (s .r .public ) > 0 {
324+ s ._highest [from ] = entry
325+ changed = true
326+ }
327+ }
293328
294329 // If there's an existing entry then make sure that we aren't being misled
295330 // by someone replaying an update we've already seen or by flooding us with
@@ -303,22 +338,17 @@ func (s *state) _handleBootstrap(from, to *peer, rx *types.Frame) bool {
303338 }
304339 }
305340
306- // Create and install the new routing table entry.
307- s ._ordering ++
308- entry := & virtualSnakeEntry {
309- virtualSnakeIndex : & index ,
310- Source : from ,
311- Destination : to ,
312- LastSeen : time .Now (),
313- Watermark : types.VirtualSnakeWatermark {
314- PublicKey : index .PublicKey ,
315- Sequence : bootstrap .Sequence ,
316- },
317- Ordering : s ._ordering ,
318- }
341+ // Install the new routing table entry.
319342 s ._table [index ] = entry
343+ s ._updateDescending (rx , index )
344+ if changed && s ._getHighest () == entry {
345+ defer s ._flood (from , rx )
346+ }
347+
348+ return true
349+ }
320350
321- // Now let's see if this is a suitable descending entry.
351+ func ( s * state ) _updateDescending ( rx * types. Frame , index virtualSnakeIndex ) {
322352 update := false
323353 desc := s ._descending
324354 switch {
@@ -350,34 +380,4 @@ func (s *state) _handleBootstrap(from, to *peer, rx *types.Frame) bool {
350380 if update {
351381 s ._setDescendingNode (s ._table [index ])
352382 }
353-
354- // Update our entry for the highest public key we've seen via this peer.
355- // If we haven't got an entry then we'll accept it as long as it's stronger
356- // than our own key. If we have got an entry then we'll accept it if the
357- // sequence number is higher or the key is stronger. If the chosen update
358- // ends up being our best highest entry, we'll flood it to all of our peers.
359- if highest , ok := s ._highest [from ]; ! ok || ! highest .valid () {
360- diff := index .PublicKey .CompareTo (s .r .public )
361- switch {
362- case diff <= 0 :
363- break
364- default :
365- s ._highest [from ] = entry
366- }
367- } else if s ._highest [from ].valid () {
368- diff := index .PublicKey .CompareTo (highest .PublicKey )
369- switch {
370- case diff < 0 :
371- break
372- case diff == 0 && bootstrap .Sequence <= highest .Watermark .Sequence :
373- break
374- default :
375- s ._highest [from ] = entry
376- }
377- }
378- if s ._getHighest () == entry {
379- defer s ._flood (from , rx )
380- }
381-
382- return true
383383}
0 commit comments