mirror of
https://github.com/slackhq/nebula.git
synced 2025-11-12 00:13:59 +01:00
Move inside packet handlers into map
This commit moves the inside packet handlers into a map of functions from the large switch statement. The functions are mapped by packet protocol version, type and subtype; which makes it simpler to inject either a new protocol version and/or custom handlers.
This commit is contained in:
parent
0d6b55e495
commit
2c931d5691
86
handler.go
Normal file
86
handler.go
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package nebula
|
||||||
|
|
||||||
|
func (f *Interface) handleMessagePacket(hostInfo *HostInfo, ci *ConnectionState, addr *udpAddr, header *Header, out []byte, packet []byte, fwPacket *FirewallPacket, nb []byte) {
|
||||||
|
if !f.handleEncrypted(ci, addr, header) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
f.decryptToTun(hostInfo, header.MessageCounter, out, packet, fwPacket, nb)
|
||||||
|
|
||||||
|
f.handleHostRoaming(hostInfo, addr)
|
||||||
|
f.connectionManager.In(hostInfo.hostId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Interface) handleLighthousePacket(hostInfo *HostInfo, ci *ConnectionState, addr *udpAddr, header *Header, out []byte, packet []byte, fwPacket *FirewallPacket, nb []byte) {
|
||||||
|
f.messageMetrics.Rx(header.Type, header.Subtype, 1)
|
||||||
|
if !f.handleEncrypted(ci, addr, header) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
d, err := f.decrypt(hostInfo, header.MessageCounter, out, packet, header, nb)
|
||||||
|
if err != nil {
|
||||||
|
hostInfo.logger().WithError(err).WithField("udpAddr", addr).
|
||||||
|
WithField("packet", packet).
|
||||||
|
Error("Failed to decrypt lighthouse packet")
|
||||||
|
|
||||||
|
//TODO: maybe after build 64 is out? 06/14/2018 - NB
|
||||||
|
//f.sendRecvError(net.Addr(addr), header.RemoteIndex)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
f.lightHouse.HandleRequest(addr, hostInfo.hostId, d, hostInfo.GetCert(), f)
|
||||||
|
|
||||||
|
f.handleHostRoaming(hostInfo, addr)
|
||||||
|
f.connectionManager.In(hostInfo.hostId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Interface) handleTestPacket(hostInfo *HostInfo, ci *ConnectionState, addr *udpAddr, header *Header, out []byte, packet []byte, fwPacket *FirewallPacket, nb []byte) {
|
||||||
|
f.messageMetrics.Rx(header.Type, header.Subtype, 1)
|
||||||
|
if !f.handleEncrypted(ci, addr, header) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
d, err := f.decrypt(hostInfo, header.MessageCounter, out, packet, header, nb)
|
||||||
|
if err != nil {
|
||||||
|
hostInfo.logger().WithError(err).WithField("udpAddr", addr).
|
||||||
|
WithField("packet", packet).
|
||||||
|
Error("Failed to decrypt test packet")
|
||||||
|
|
||||||
|
//TODO: maybe after build 64 is out? 06/14/2018 - NB
|
||||||
|
//f.sendRecvError(net.Addr(addr), header.RemoteIndex)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if header.Subtype == testRequest {
|
||||||
|
// This testRequest might be from TryPromoteBest, so we should roam
|
||||||
|
// to the new IP address before responding
|
||||||
|
f.handleHostRoaming(hostInfo, addr)
|
||||||
|
f.send(test, testReply, ci, hostInfo, hostInfo.remote, d, nb, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
f.handleHostRoaming(hostInfo, addr)
|
||||||
|
f.connectionManager.In(hostInfo.hostId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Interface) handleHandshakePacket(hostInfo *HostInfo, ci *ConnectionState, addr *udpAddr, header *Header, out []byte, packet []byte, fwPacket *FirewallPacket, nb []byte) {
|
||||||
|
f.messageMetrics.Rx(header.Type, header.Subtype, 1)
|
||||||
|
HandleIncomingHandshake(f, addr, packet, header, hostInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Interface) handleRecvErrorPacket(hostInfo *HostInfo, ci *ConnectionState, addr *udpAddr, header *Header, out []byte, packet []byte, fwPacket *FirewallPacket, nb []byte) {
|
||||||
|
f.messageMetrics.Rx(header.Type, header.Subtype, 1)
|
||||||
|
// TODO: Remove this with recv_error deprecation
|
||||||
|
f.handleRecvError(addr, header)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Interface) handleCloseTunnelPacket(hostInfo *HostInfo, ci *ConnectionState, addr *udpAddr, header *Header, out []byte, packet []byte, fwPacket *FirewallPacket, nb []byte) {
|
||||||
|
f.messageMetrics.Rx(header.Type, header.Subtype, 1)
|
||||||
|
if !f.handleEncrypted(ci, addr, header) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
hostInfo.logger().WithField("udpAddr", addr).
|
||||||
|
Info("Close tunnel received, tearing down.")
|
||||||
|
|
||||||
|
f.closeTunnel(hostInfo)
|
||||||
|
}
|
||||||
@ -54,6 +54,7 @@ var typeMap = map[NebulaMessageType]string{
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
subTypeNone NebulaMessageSubType = 0
|
||||||
testRequest NebulaMessageSubType = 0
|
testRequest NebulaMessageSubType = 0
|
||||||
testReply NebulaMessageSubType = 1
|
testReply NebulaMessageSubType = 1
|
||||||
)
|
)
|
||||||
|
|||||||
28
interface.go
28
interface.go
@ -20,6 +20,8 @@ type Inside interface {
|
|||||||
WriteRaw([]byte) error
|
WriteRaw([]byte) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type InsideHandler func(hostInfo *HostInfo, ci *ConnectionState, addr *udpAddr, header *Header, out []byte, packet []byte, fp *FirewallPacket, nb []byte)
|
||||||
|
|
||||||
type InterfaceConfig struct {
|
type InterfaceConfig struct {
|
||||||
HostMap *HostMap
|
HostMap *HostMap
|
||||||
Outside *udpConn
|
Outside *udpConn
|
||||||
@ -61,6 +63,9 @@ type Interface struct {
|
|||||||
tunQueues int
|
tunQueues int
|
||||||
version string
|
version string
|
||||||
|
|
||||||
|
// handlers are mapped by protocol version -> type -> subtype
|
||||||
|
handlers map[uint8]map[NebulaMessageType]map[NebulaMessageSubType]InsideHandler
|
||||||
|
|
||||||
metricHandshakes metrics.Histogram
|
metricHandshakes metrics.Histogram
|
||||||
messageMetrics *MessageMetrics
|
messageMetrics *MessageMetrics
|
||||||
}
|
}
|
||||||
@ -103,6 +108,29 @@ func NewInterface(c *InterfaceConfig) (*Interface, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ifce.connectionManager = newConnectionManager(ifce, c.checkInterval, c.pendingDeletionInterval)
|
ifce.connectionManager = newConnectionManager(ifce, c.checkInterval, c.pendingDeletionInterval)
|
||||||
|
ifce.handlers = map[uint8]map[NebulaMessageType]map[NebulaMessageSubType]InsideHandler{
|
||||||
|
Version: {
|
||||||
|
handshake: {
|
||||||
|
handshakeIXPSK0: ifce.handleHandshakePacket,
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
subTypeNone: ifce.handleMessagePacket,
|
||||||
|
},
|
||||||
|
recvError: {
|
||||||
|
subTypeNone: ifce.handleRecvErrorPacket,
|
||||||
|
},
|
||||||
|
lightHouse: {
|
||||||
|
subTypeNone: ifce.handleLighthousePacket,
|
||||||
|
},
|
||||||
|
test: {
|
||||||
|
testRequest: ifce.handleTestPacket,
|
||||||
|
testReply: ifce.handleTestPacket,
|
||||||
|
},
|
||||||
|
closeTunnel: {
|
||||||
|
subTypeNone: ifce.handleCloseTunnelPacket,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
return ifce, nil
|
return ifce, nil
|
||||||
}
|
}
|
||||||
|
|||||||
89
outside.go
89
outside.go
@ -39,98 +39,15 @@ func (f *Interface) readOutsidePackets(addr *udpAddr, out []byte, packet []byte,
|
|||||||
ci = hostinfo.ConnectionState
|
ci = hostinfo.ConnectionState
|
||||||
}
|
}
|
||||||
|
|
||||||
switch header.Type {
|
handle := f.handlers[header.Version][header.Type][header.Subtype]
|
||||||
case message:
|
|
||||||
if !f.handleEncrypted(ci, addr, header) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
f.decryptToTun(hostinfo, header.MessageCounter, out, packet, fwPacket, nb)
|
if handle == nil {
|
||||||
|
|
||||||
// Fallthrough to the bottom to record incoming traffic
|
|
||||||
|
|
||||||
case lightHouse:
|
|
||||||
f.messageMetrics.Rx(header.Type, header.Subtype, 1)
|
|
||||||
if !f.handleEncrypted(ci, addr, header) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
d, err := f.decrypt(hostinfo, header.MessageCounter, out, packet, header, nb)
|
|
||||||
if err != nil {
|
|
||||||
hostinfo.logger().WithError(err).WithField("udpAddr", addr).
|
|
||||||
WithField("packet", packet).
|
|
||||||
Error("Failed to decrypt lighthouse packet")
|
|
||||||
|
|
||||||
//TODO: maybe after build 64 is out? 06/14/2018 - NB
|
|
||||||
//f.sendRecvError(net.Addr(addr), header.RemoteIndex)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
f.lightHouse.HandleRequest(addr, hostinfo.hostId, d, hostinfo.GetCert(), f)
|
|
||||||
|
|
||||||
// Fallthrough to the bottom to record incoming traffic
|
|
||||||
|
|
||||||
case test:
|
|
||||||
f.messageMetrics.Rx(header.Type, header.Subtype, 1)
|
|
||||||
if !f.handleEncrypted(ci, addr, header) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
d, err := f.decrypt(hostinfo, header.MessageCounter, out, packet, header, nb)
|
|
||||||
if err != nil {
|
|
||||||
hostinfo.logger().WithError(err).WithField("udpAddr", addr).
|
|
||||||
WithField("packet", packet).
|
|
||||||
Error("Failed to decrypt test packet")
|
|
||||||
|
|
||||||
//TODO: maybe after build 64 is out? 06/14/2018 - NB
|
|
||||||
//f.sendRecvError(net.Addr(addr), header.RemoteIndex)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if header.Subtype == testRequest {
|
|
||||||
// This testRequest might be from TryPromoteBest, so we should roam
|
|
||||||
// to the new IP address before responding
|
|
||||||
f.handleHostRoaming(hostinfo, addr)
|
|
||||||
f.send(test, testReply, ci, hostinfo, hostinfo.remote, d, nb, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallthrough to the bottom to record incoming traffic
|
|
||||||
|
|
||||||
// Non encrypted messages below here, they should not fall through to avoid tracking incoming traffic since they
|
|
||||||
// are unauthenticated
|
|
||||||
|
|
||||||
case handshake:
|
|
||||||
f.messageMetrics.Rx(header.Type, header.Subtype, 1)
|
|
||||||
HandleIncomingHandshake(f, addr, packet, header, hostinfo)
|
|
||||||
return
|
|
||||||
|
|
||||||
case recvError:
|
|
||||||
f.messageMetrics.Rx(header.Type, header.Subtype, 1)
|
|
||||||
// TODO: Remove this with recv_error deprecation
|
|
||||||
f.handleRecvError(addr, header)
|
|
||||||
return
|
|
||||||
|
|
||||||
case closeTunnel:
|
|
||||||
f.messageMetrics.Rx(header.Type, header.Subtype, 1)
|
|
||||||
if !f.handleEncrypted(ci, addr, header) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
hostinfo.logger().WithField("udpAddr", addr).
|
|
||||||
Info("Close tunnel received, tearing down.")
|
|
||||||
|
|
||||||
f.closeTunnel(hostinfo)
|
|
||||||
return
|
|
||||||
|
|
||||||
default:
|
|
||||||
f.messageMetrics.Rx(header.Type, header.Subtype, 1)
|
f.messageMetrics.Rx(header.Type, header.Subtype, 1)
|
||||||
hostinfo.logger().Debugf("Unexpected packet received from %s", addr)
|
hostinfo.logger().Debugf("Unexpected packet received from %s", addr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
f.handleHostRoaming(hostinfo, addr)
|
handle(hostinfo, ci, addr, header, out, packet, fwPacket, nb)
|
||||||
|
|
||||||
f.connectionManager.In(hostinfo.hostId)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Interface) closeTunnel(hostInfo *HostInfo) {
|
func (f *Interface) closeTunnel(hostInfo *HostInfo) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user