mirror of
https://github.com/slackhq/nebula.git
synced 2026-08-16 00:47:02 +02:00
readOutsidePackets had too many args
This commit is contained in:
+28
-9
@@ -349,6 +349,31 @@ func (f *Interface) onFatal(err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type rxContext struct {
|
||||||
|
q int
|
||||||
|
scratch []byte
|
||||||
|
// nb is a re-usable nonce buffer for decrypt calls to use
|
||||||
|
nb []byte
|
||||||
|
h *header.H
|
||||||
|
fwPacket *firewall.ParsedPacket
|
||||||
|
hostmapCache map[uint32]*HostInfo
|
||||||
|
lhh *LightHouseHandler
|
||||||
|
ctCache *firewall.ConntrackCacheTicker
|
||||||
|
}
|
||||||
|
|
||||||
|
func newRxContext(f *Interface, q int) *rxContext {
|
||||||
|
return &rxContext{
|
||||||
|
q: q,
|
||||||
|
scratch: make([]byte, mtu),
|
||||||
|
nb: make([]byte, 12, 12),
|
||||||
|
h: &header.H{},
|
||||||
|
fwPacket: &firewall.ParsedPacket{},
|
||||||
|
hostmapCache: map[uint32]*HostInfo{},
|
||||||
|
lhh: f.lightHouse.NewRequestHandler(),
|
||||||
|
ctCache: firewall.NewConntrackCacheTicker(f.ctx, f.l, f.conntrackCacheTimeout),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (f *Interface) listenOut(i int) {
|
func (f *Interface) listenOut(i int) {
|
||||||
var li udp.Conn
|
var li udp.Conn
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
@@ -357,23 +382,17 @@ func (f *Interface) listenOut(i int) {
|
|||||||
li = f.outside
|
li = f.outside
|
||||||
}
|
}
|
||||||
|
|
||||||
ctCache := firewall.NewConntrackCacheTicker(f.ctx, f.l, f.conntrackCacheTimeout)
|
rxc := newRxContext(f, i)
|
||||||
lhh := f.lightHouse.NewRequestHandler()
|
|
||||||
h := &header.H{}
|
|
||||||
fwPacket := &firewall.ParsedPacket{}
|
|
||||||
nb := make([]byte, 12, 12)
|
|
||||||
scratch := make([]byte, mtu)
|
|
||||||
hostmapCache := map[uint32]*HostInfo{} //todo is this stupid
|
|
||||||
|
|
||||||
listener := func(fromUdpAddr netip.AddrPort, payload []byte) {
|
listener := func(fromUdpAddr netip.AddrPort, payload []byte) {
|
||||||
f.readOutsidePackets(ViaSender{UdpAddr: fromUdpAddr}, scratch, payload, h, fwPacket, lhh, nb, i, ctCache.Get(), hostmapCache)
|
f.readOutsidePackets(ViaSender{UdpAddr: fromUdpAddr}, payload, rxc)
|
||||||
}
|
}
|
||||||
|
|
||||||
flusher := func() {
|
flusher := func() {
|
||||||
if err := f.batchers[i].Flush(); err != nil {
|
if err := f.batchers[i].Flush(); err != nil {
|
||||||
f.l.Error("Failed to flush tun coalescer", "error", err)
|
f.l.Error("Failed to flush tun coalescer", "error", err)
|
||||||
}
|
}
|
||||||
clear(hostmapCache)
|
clear(rxc.hostmapCache)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := li.ListenOut(listener, flusher)
|
err := li.ListenOut(listener, flusher)
|
||||||
|
|||||||
+21
-25
@@ -26,7 +26,8 @@ var ErrOutOfWindow = errors.New("out of window packet")
|
|||||||
// readOutsidePackets processes one received underlay packet.
|
// readOutsidePackets processes one received underlay packet.
|
||||||
// Message payloads are decrypted IN PLACE, so packet must stay untouched
|
// Message payloads are decrypted IN PLACE, so packet must stay untouched
|
||||||
// by the caller until the batcher for queue q has been flushed
|
// by the caller until the batcher for queue q has been flushed
|
||||||
func (f *Interface) readOutsidePackets(via ViaSender, scratch []byte, packet []byte, h *header.H, fwPacket *firewall.ParsedPacket, lhf *LightHouseHandler, nb []byte, q int, localCache firewall.ConntrackCache, hmCache map[uint32]*HostInfo) {
|
func (f *Interface) readOutsidePackets(via ViaSender, packet []byte, rxc *rxContext) {
|
||||||
|
h := rxc.h
|
||||||
err := h.Parse(packet)
|
err := h.Parse(packet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Hole punch packets are 0 or 1 byte big, so lets ignore printing those errors
|
// Hole punch packets are 0 or 1 byte big, so lets ignore printing those errors
|
||||||
@@ -94,7 +95,7 @@ func (f *Interface) readOutsidePackets(via ViaSender, scratch []byte, packet []b
|
|||||||
if isMessageRelay {
|
if isMessageRelay {
|
||||||
hostinfo = f.hostMap.QueryRelayIndex(h.RemoteIndex)
|
hostinfo = f.hostMap.QueryRelayIndex(h.RemoteIndex)
|
||||||
} else {
|
} else {
|
||||||
hostinfo = f.hostMap.QueryIndexCached(h.RemoteIndex, hmCache)
|
hostinfo = f.hostMap.QueryIndexCached(h.RemoteIndex, rxc.hostmapCache)
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point we should have a valid existing tunnel, verify and send
|
// At this point we should have a valid existing tunnel, verify and send
|
||||||
@@ -117,18 +118,18 @@ func (f *Interface) readOutsidePackets(via ViaSender, scratch []byte, packet []b
|
|||||||
// All remaining packets are encrypted
|
// All remaining packets are encrypted
|
||||||
if isMessageRelay {
|
if isMessageRelay {
|
||||||
// Relay packets are special, this branch should always early-return
|
// Relay packets are special, this branch should always early-return
|
||||||
err = hostinfo.ConnectionState.VerifyRelay(f.l, h.MessageCounter, packet, nb)
|
err = hostinfo.ConnectionState.VerifyRelay(f.l, h.MessageCounter, packet, rxc.nb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if f.l.Enabled(context.Background(), slog.LevelDebug) {
|
if f.l.Enabled(context.Background(), slog.LevelDebug) {
|
||||||
hostinfo.logger(f.l).Debug("Failed to verify relay packet", "error", err, "from", via, "header", h)
|
hostinfo.logger(f.l).Debug("Failed to verify relay packet", "error", err, "from", via, "header", h)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
f.handleOutsideRelayPacket(hostinfo, via, scratch, packet, h, fwPacket, lhf, nb, q, localCache, hmCache)
|
f.handleOutsideRelayPacket(hostinfo, via, packet, rxc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
out, err := hostinfo.ConnectionState.Decrypt(f.l, h.MessageCounter, packet, nb)
|
out, err := hostinfo.ConnectionState.Decrypt(f.l, h.MessageCounter, packet, rxc.nb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if f.l.Enabled(context.Background(), slog.LevelDebug) {
|
if f.l.Enabled(context.Background(), slog.LevelDebug) {
|
||||||
hostinfo.logger(f.l).Debug("Failed to decrypt packet", "error", err, "from", via, "header", h)
|
hostinfo.logger(f.l).Debug("Failed to decrypt packet", "error", err, "from", via, "header", h)
|
||||||
@@ -144,7 +145,7 @@ func (f *Interface) readOutsidePackets(via ViaSender, scratch []byte, packet []b
|
|||||||
case header.Message:
|
case header.Message:
|
||||||
switch h.Subtype {
|
switch h.Subtype {
|
||||||
case header.MessageNone:
|
case header.MessageNone:
|
||||||
f.handleOutsideMessagePacket(hostinfo, h.MessageCounter, out, scratch, fwPacket, nb, q, localCache)
|
f.handleOutsideMessagePacket(hostinfo, h.MessageCounter, out, rxc)
|
||||||
default:
|
default:
|
||||||
hostinfo.logger(f.l).Error("IsValidSubType was true, but unexpected message subtype seen", "from", via, "header", h)
|
hostinfo.logger(f.l).Error("IsValidSubType was true, but unexpected message subtype seen", "from", via, "header", h)
|
||||||
return
|
return
|
||||||
@@ -152,7 +153,7 @@ func (f *Interface) readOutsidePackets(via ViaSender, scratch []byte, packet []b
|
|||||||
|
|
||||||
case header.LightHouse:
|
case header.LightHouse:
|
||||||
//TODO: assert via is not relayed
|
//TODO: assert via is not relayed
|
||||||
lhf.HandleRequest(via.UdpAddr, hostinfo.vpnAddrs, out, f)
|
rxc.lhh.HandleRequest(via.UdpAddr, hostinfo.vpnAddrs, out, f)
|
||||||
|
|
||||||
case header.Test:
|
case header.Test:
|
||||||
switch h.Subtype {
|
switch h.Subtype {
|
||||||
@@ -161,14 +162,14 @@ func (f *Interface) readOutsidePackets(via ViaSender, scratch []byte, packet []b
|
|||||||
case header.TestRequest:
|
case header.TestRequest:
|
||||||
const maxCipherOverhead = 16 //todo we use this too often, needs a real importable const
|
const maxCipherOverhead = 16 //todo we use this too often, needs a real importable const
|
||||||
const maxOverhead = header.Len + header.Len + maxCipherOverhead + maxCipherOverhead
|
const maxOverhead = header.Len + header.Len + maxCipherOverhead + maxCipherOverhead
|
||||||
if maxOverhead+len(out) > len(scratch) {
|
if maxOverhead+len(out) > len(rxc.scratch) {
|
||||||
// A reply that cannot fit in scratch is dropped no matter the log level.
|
// A reply that cannot fit in scratch is dropped no matter the log level.
|
||||||
if f.l.Enabled(context.Background(), slog.LevelDebug) {
|
if f.l.Enabled(context.Background(), slog.LevelDebug) {
|
||||||
hostinfo.logger(f.l).Debug("dropping oversized test request", "payloadLen", len(out), "from", via)
|
hostinfo.logger(f.l).Debug("dropping oversized test request", "payloadLen", len(out), "from", via)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
f.send(header.Test, header.TestReply, hostinfo.ConnectionState, hostinfo, out, nb, scratch[:0])
|
f.send(header.Test, header.TestReply, hostinfo.ConnectionState, hostinfo, out, rxc.nb, rxc.scratch[:0])
|
||||||
default:
|
default:
|
||||||
hostinfo.logger(f.l).Error("IsValidSubType was true, but unexpected test subtype seen", "from", via, "header", h)
|
hostinfo.logger(f.l).Error("IsValidSubType was true, but unexpected test subtype seen", "from", via, "header", h)
|
||||||
return
|
return
|
||||||
@@ -186,7 +187,8 @@ func (f *Interface) readOutsidePackets(via ViaSender, scratch []byte, packet []b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Interface) handleOutsideRelayPacket(hostinfo *HostInfo, via ViaSender, scratch []byte, packet []byte, h *header.H, fwPacket *firewall.ParsedPacket, lhf *LightHouseHandler, nb []byte, q int, localCache firewall.ConntrackCache, hmCache map[uint32]*HostInfo) {
|
func (f *Interface) handleOutsideRelayPacket(hostinfo *HostInfo, via ViaSender, packet []byte, rxc *rxContext) {
|
||||||
|
h := rxc.h
|
||||||
// Successfully validated the thing. Get rid of the Relay header and the AEAD tag
|
// Successfully validated the thing. Get rid of the Relay header and the AEAD tag
|
||||||
signedPayload := packet[header.Len : len(packet)-hostinfo.ConnectionState.dKey.Overhead()]
|
signedPayload := packet[header.Len : len(packet)-hostinfo.ConnectionState.dKey.Overhead()]
|
||||||
// Pull the Roaming parts up here, and return in all call paths.
|
// Pull the Roaming parts up here, and return in all call paths.
|
||||||
@@ -213,7 +215,7 @@ func (f *Interface) handleOutsideRelayPacket(hostinfo *HostInfo, via ViaSender,
|
|||||||
relay: relay,
|
relay: relay,
|
||||||
IsRelayed: true,
|
IsRelayed: true,
|
||||||
}
|
}
|
||||||
f.readOutsidePackets(via, scratch, signedPayload, h, fwPacket, lhf, nb, q, localCache, hmCache)
|
f.readOutsidePackets(via, signedPayload, rxc)
|
||||||
case ForwardingType:
|
case ForwardingType:
|
||||||
// Find the target HostInfo relay object
|
// Find the target HostInfo relay object
|
||||||
targetHI, targetRelay, err := f.hostMap.QueryVpnAddrsRelayFor(hostinfo.vpnAddrs, relay.PeerAddr)
|
targetHI, targetRelay, err := f.hostMap.QueryVpnAddrsRelayFor(hostinfo.vpnAddrs, relay.PeerAddr)
|
||||||
@@ -234,7 +236,7 @@ func (f *Interface) handleOutsideRelayPacket(hostinfo *HostInfo, via ViaSender,
|
|||||||
// Encode overwrites the old outer header, and the new AEAD tag lands where the old one was
|
// Encode overwrites the old outer header, and the new AEAD tag lands where the old one was
|
||||||
fwdBuf := packet[:0]
|
fwdBuf := packet[:0]
|
||||||
//todo it would potentially be nice to batch these
|
//todo it would potentially be nice to batch these
|
||||||
f.SendVia(targetHI, targetRelay, signedPayload, nb, fwdBuf, true, q)
|
f.SendVia(targetHI, targetRelay, signedPayload, rxc.nb, fwdBuf, true, rxc.q)
|
||||||
case TerminalType:
|
case TerminalType:
|
||||||
hostinfo.logger(f.l).Error("Unexpected Relay Type of Terminal")
|
hostinfo.logger(f.l).Error("Unexpected Relay Type of Terminal")
|
||||||
return
|
return
|
||||||
@@ -517,29 +519,23 @@ func parseV4(data []byte, incoming bool, fp *firewall.ParsedPacket) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Interface) handleOutsideMessagePacket(hostinfo *HostInfo, messageCounter uint64, out []byte, scratch []byte, fwPacket *firewall.ParsedPacket, nb []byte, q int, localCache firewall.ConntrackCache) {
|
func (f *Interface) handleOutsideMessagePacket(hostinfo *HostInfo, messageCounter uint64, out []byte, rxc *rxContext) {
|
||||||
err := newPacket(out, true, fwPacket)
|
err := newPacket(out, true, rxc.fwPacket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hostinfo.logger(f.l).Warn("Error while validating inbound packet",
|
hostinfo.logger(f.l).Warn("Error while validating inbound packet", "error", err, "packet", out)
|
||||||
"error", err,
|
|
||||||
"packet", out,
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
dropReason := f.firewall.Drop(fwPacket.Packet, true, hostinfo, f.pki.GetCAPool(), localCache)
|
dropReason := f.firewall.Drop(rxc.fwPacket.Packet, true, hostinfo, f.pki.GetCAPool(), rxc.ctCache.Get())
|
||||||
if dropReason != nil {
|
if dropReason != nil {
|
||||||
f.rejectOutside(out, hostinfo.ConnectionState, hostinfo, nb, scratch, q)
|
f.rejectOutside(out, hostinfo.ConnectionState, hostinfo, rxc.nb, rxc.scratch, rxc.q)
|
||||||
if f.l.Enabled(context.Background(), slog.LevelDebug) {
|
if f.l.Enabled(context.Background(), slog.LevelDebug) {
|
||||||
hostinfo.logger(f.l).Debug("dropping inbound packet",
|
hostinfo.logger(f.l).Debug("dropping inbound packet", "fwPacket", rxc.fwPacket, "reason", dropReason)
|
||||||
"fwPacket", fwPacket,
|
|
||||||
"reason", dropReason,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = f.batchers[q].Commit(out, batch.SortKey{Epoch: hostinfo.ConnectionState.epoch, Counter: messageCounter}, fwPacket)
|
err = f.batchers[rxc.q].Commit(out, batch.SortKey{Epoch: hostinfo.ConnectionState.epoch, Counter: messageCounter}, rxc.fwPacket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f.l.Error("Failed to write to tun", "error", err)
|
f.l.Error("Failed to write to tun", "error", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user