mirror of
https://github.com/slackhq/nebula.git
synced 2026-11-15 08:36:52 +01:00
Find a refused packet's tunnel from its header, ask the lighthouse when probing, and address review
This commit is contained in:
1 parent
0f07faab0e
commit
b69cf4ecb4
11 files changed
+306
-41
No files matched your search
+25
-8
@@ -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){
|
||||
|
||||
Reference in new issue
Block a user