mirror of
https://github.com/slackhq/nebula.git
synced 2025-11-11 23:03:57 +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 (
|
||||
subTypeNone NebulaMessageSubType = 0
|
||||
testRequest NebulaMessageSubType = 0
|
||||
testReply NebulaMessageSubType = 1
|
||||
)
|
||||
|
||||
28
interface.go
28
interface.go
@ -20,6 +20,8 @@ type Inside interface {
|
||||
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 {
|
||||
HostMap *HostMap
|
||||
Outside *udpConn
|
||||
@ -61,6 +63,9 @@ type Interface struct {
|
||||
tunQueues int
|
||||
version string
|
||||
|
||||
// handlers are mapped by protocol version -> type -> subtype
|
||||
handlers map[uint8]map[NebulaMessageType]map[NebulaMessageSubType]InsideHandler
|
||||
|
||||
metricHandshakes metrics.Histogram
|
||||
messageMetrics *MessageMetrics
|
||||
}
|
||||
@ -103,6 +108,29 @@ func NewInterface(c *InterfaceConfig) (*Interface, error) {
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
89
outside.go
89
outside.go
@ -39,98 +39,15 @@ func (f *Interface) readOutsidePackets(addr *udpAddr, out []byte, packet []byte,
|
||||
ci = hostinfo.ConnectionState
|
||||
}
|
||||
|
||||
switch header.Type {
|
||||
case message:
|
||||
if !f.handleEncrypted(ci, addr, header) {
|
||||
return
|
||||
}
|
||||
handle := f.handlers[header.Version][header.Type][header.Subtype]
|
||||
|
||||
f.decryptToTun(hostinfo, header.MessageCounter, out, packet, fwPacket, nb)
|
||||
|
||||
// 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:
|
||||
if handle == nil {
|
||||
f.messageMetrics.Rx(header.Type, header.Subtype, 1)
|
||||
hostinfo.logger().Debugf("Unexpected packet received from %s", addr)
|
||||
return
|
||||
}
|
||||
|
||||
f.handleHostRoaming(hostinfo, addr)
|
||||
|
||||
f.connectionManager.In(hostinfo.hostId)
|
||||
handle(hostinfo, ci, addr, header, out, packet, fwPacket, nb)
|
||||
}
|
||||
|
||||
func (f *Interface) closeTunnel(hostInfo *HostInfo) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user