Find a refused packet's tunnel from its header, ask the lighthouse when probing, and address review

This commit is contained in:
JackDoan committed 2026-10-20 14:17:13 -05:00
1 parent 0f07faab0e
commit b69cf4ecb4
11 files changed
+306 -41

No files matched your search

+25 -8
View File
@@ -1,6 +1,7 @@
package nebula
import (
"bytes"
"context"
"crypto/fips140"
"errors"
@@ -507,24 +508,40 @@ func (f *Interface) flushSendBatch(sb *batch.SendBatch, q int) {
f.metricTxDropped.Inc(int64(dropped))
}
// Packets are tagged with the local index of the tunnel they belong to. A tunnel's packets tend to fail together,
// so skip straight past a repeat of the one before.
// A tunnel's packets tend to fail together, so skip straight past a repeat of the one before. The first 8 bytes
// of a header say whose packet it is, the counter after them changes with every packet.
var last batch.Failure
for i, fail := range sb.Failures() {
if i > 0 && fail.Tag == last.Tag && fail.Dst == last.Dst {
if i > 0 && fail.Dst == last.Dst && bytes.Equal(fail.Head[:8], last.Head[:8]) {
continue
}
last = fail
if !udp.IsUnreachable(fail.Err) {
continue
}
if hostinfo := f.hostMap.QueryIndex(fail.Tag); hostinfo != nil {
hostinfo.remoteUnreachable(f, fail.Dst)
if udp.IsUnreachable(fail.Err) {
f.sendUnreachable(fail.Head[:], fail.Dst)
}
}
}
// sendUnreachable finds the tunnel a packet we had no route for was sent on, from the start of the packet, and has it
// look for another path to its peer.
func (f *Interface) sendUnreachable(head []byte, dst netip.AddrPort) {
var h header.H
if h.Parse(head) != nil {
return
}
if h.Type == header.Message && h.Subtype == header.MessageRelay {
// TODO: a relayed packet's header carries the relay session's index, not the relay tunnel's, so it does not
// lead us to the tunnel whose remote failed. The relay tunnel's own traffic finds out soon enough.
return
}
if hostinfo := f.hostMap.QueryReverseIndex(h.RemoteIndex); hostinfo != nil {
hostinfo.remoteUnreachable(f, dst)
}
}
func (f *Interface) RegisterConfigChangeCallbacks(c *config.C) {
c.RegisterReloadCallback(f.reloadFirewall)
for _, reload := range []func(*config.C){