mirror of
https://github.com/slackhq/nebula.git
synced 2025-12-31 02:58:28 +01:00
avoid heap problems
This commit is contained in:
24
outside.go
24
outside.go
@@ -22,19 +22,18 @@ const (
|
|||||||
|
|
||||||
// handleRelayPackets handles relay packets. Returns false if there's nothing left to do, true for continuing to process an unwrapped TerminalType packet
|
// handleRelayPackets handles relay packets. Returns false if there's nothing left to do, true for continuing to process an unwrapped TerminalType packet
|
||||||
// scratch must be large enough to contain a packet to be relayed if needed
|
// scratch must be large enough to contain a packet to be relayed if needed
|
||||||
func (f *Interface) handleRelayPackets(via ViaSender, hostinfo *HostInfo, segment *[]byte, scratch []byte, h *header.H, nb []byte) (*ViaSender, bool) {
|
func (f *Interface) handleRelayPackets(via ViaSender, hostinfo *HostInfo, segment []byte, scratch []byte, h *header.H, nb []byte) ([]byte, *ViaSender, bool) {
|
||||||
var err error
|
var err error
|
||||||
// The entire body is sent as AD, not encrypted.
|
// The entire body is sent as AD, not encrypted.
|
||||||
// The packet consists of a 16-byte parsed Nebula header, Associated Data-protected payload, and a trailing 16-byte AEAD signature value.
|
// The packet consists of a 16-byte parsed Nebula header, Associated Data-protected payload, and a trailing 16-byte AEAD signature value.
|
||||||
// The packet is guaranteed to be at least 16 bytes at this point, b/c it got past the h.Parse() call above. If it's
|
// The packet is guaranteed to be at least 16 bytes at this point, b/c it got past the h.Parse() call above. If it's
|
||||||
// otherwise malformed (meaning, there is no trailing 16 byte AEAD value), then this will result in at worst a 0-length slice
|
// otherwise malformed (meaning, there is no trailing 16 byte AEAD value), then this will result in at worst a 0-length slice
|
||||||
// which will gracefully fail in the DecryptDanger call.
|
// which will gracefully fail in the DecryptDanger call.
|
||||||
seg := *segment
|
signedPayload := segment[:len(segment)-hostinfo.ConnectionState.dKey.Overhead()]
|
||||||
signedPayload := seg[:len(*segment)-hostinfo.ConnectionState.dKey.Overhead()]
|
signatureValue := segment[len(segment)-hostinfo.ConnectionState.dKey.Overhead():]
|
||||||
signatureValue := seg[len(*segment)-hostinfo.ConnectionState.dKey.Overhead():]
|
|
||||||
scratch, err = hostinfo.ConnectionState.dKey.DecryptDanger(scratch, signedPayload, signatureValue, h.MessageCounter, nb)
|
scratch, err = hostinfo.ConnectionState.dKey.DecryptDanger(scratch, signedPayload, signatureValue, h.MessageCounter, nb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false
|
return nil, nil, false
|
||||||
}
|
}
|
||||||
// Successfully validated the thing. Get rid of the Relay header.
|
// Successfully validated the thing. Get rid of the Relay header.
|
||||||
signedPayload = signedPayload[header.Len:]
|
signedPayload = signedPayload[header.Len:]
|
||||||
@@ -49,7 +48,7 @@ func (f *Interface) handleRelayPackets(via ViaSender, hostinfo *HostInfo, segmen
|
|||||||
// The only way this happens is if hostmap has an index to the correct HostInfo, but the HostInfo is missing
|
// The only way this happens is if hostmap has an index to the correct HostInfo, but the HostInfo is missing
|
||||||
// its internal mapping. This should never happen.
|
// its internal mapping. This should never happen.
|
||||||
hostinfo.logger(f.l).WithFields(logrus.Fields{"vpnAddrs": hostinfo.vpnAddrs, "remoteIndex": h.RemoteIndex}).Error("HostInfo missing remote relay index")
|
hostinfo.logger(f.l).WithFields(logrus.Fields{"vpnAddrs": hostinfo.vpnAddrs, "remoteIndex": h.RemoteIndex}).Error("HostInfo missing remote relay index")
|
||||||
return nil, false
|
return nil, nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
switch relay.Type {
|
switch relay.Type {
|
||||||
@@ -65,7 +64,7 @@ func (f *Interface) handleRelayPackets(via ViaSender, hostinfo *HostInfo, segmen
|
|||||||
if len(signedPayload) > 1 {
|
if len(signedPayload) > 1 {
|
||||||
f.l.WithField("packet", segment).Infof("Error while parsing inbound packet from %s: %s", via, err)
|
f.l.WithField("packet", segment).Infof("Error while parsing inbound packet from %s: %s", via, err)
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, nil, false
|
||||||
}
|
}
|
||||||
newVia := &ViaSender{
|
newVia := &ViaSender{
|
||||||
UdpAddr: via.UdpAddr,
|
UdpAddr: via.UdpAddr,
|
||||||
@@ -74,15 +73,14 @@ func (f *Interface) handleRelayPackets(via ViaSender, hostinfo *HostInfo, segmen
|
|||||||
relay: relay,
|
relay: relay,
|
||||||
IsRelayed: true,
|
IsRelayed: true,
|
||||||
}
|
}
|
||||||
*segment = signedPayload
|
|
||||||
//continue flowing through readOutsideSegment()
|
//continue flowing through readOutsideSegment()
|
||||||
return newVia, true
|
return signedPayload, newVia, true
|
||||||
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)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hostinfo.logger(f.l).WithField("relayTo", relay.PeerAddr).WithError(err).WithField("hostinfo.vpnAddrs", hostinfo.vpnAddrs).Info("Failed to find target host info by ip")
|
hostinfo.logger(f.l).WithField("relayTo", relay.PeerAddr).WithError(err).WithField("hostinfo.vpnAddrs", hostinfo.vpnAddrs).Info("Failed to find target host info by ip")
|
||||||
return nil, false
|
return nil, nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// If that relay is Established, forward the payload through it
|
// If that relay is Established, forward the payload through it
|
||||||
@@ -100,7 +98,7 @@ func (f *Interface) handleRelayPackets(via ViaSender, hostinfo *HostInfo, segmen
|
|||||||
hostinfo.logger(f.l).WithFields(logrus.Fields{"relayTo": relay.PeerAddr, "relayFrom": hostinfo.vpnAddrs[0], "targetRelayState": targetRelay.State}).Info("Unexpected target relay state")
|
hostinfo.logger(f.l).WithFields(logrus.Fields{"relayTo": relay.PeerAddr, "relayFrom": hostinfo.vpnAddrs[0], "targetRelayState": targetRelay.State}).Info("Unexpected target relay state")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Interface) readOutsideSegment(via ViaSender, segment []byte, out *packet.OutPacket, lhf *LightHouseHandler, s *Scratches, q int, localCache firewall.ConntrackCache, now time.Time) {
|
func (f *Interface) readOutsideSegment(via ViaSender, segment []byte, out *packet.OutPacket, lhf *LightHouseHandler, s *Scratches, q int, localCache firewall.ConntrackCache, now time.Time) {
|
||||||
@@ -118,12 +116,12 @@ func (f *Interface) readOutsideSegment(via ViaSender, segment []byte, out *packe
|
|||||||
// verify if we've seen this index before, otherwise respond to the handshake initiation
|
// verify if we've seen this index before, otherwise respond to the handshake initiation
|
||||||
if h.Type == header.Message && h.Subtype == header.MessageRelay {
|
if h.Type == header.Message && h.Subtype == header.MessageRelay {
|
||||||
hostinfo = f.hostMap.QueryRelayIndex(h.RemoteIndex)
|
hostinfo = f.hostMap.QueryRelayIndex(h.RemoteIndex)
|
||||||
newVia, keepGoing := f.handleRelayPackets(via, hostinfo, &segment, s.scratch, h, s.nb)
|
newSegment, newVia, keepGoing := f.handleRelayPackets(via, hostinfo, segment, s.scratch, h, s.nb)
|
||||||
if !keepGoing {
|
if !keepGoing {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
via = *newVia
|
via = *newVia
|
||||||
|
segment = newSegment
|
||||||
} else {
|
} else {
|
||||||
hostinfo = f.hostMap.QueryIndex(h.RemoteIndex)
|
hostinfo = f.hostMap.QueryIndex(h.RemoteIndex)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user