mirror of
https://github.com/slackhq/nebula.git
synced 2025-11-09 23:43:57 +01:00
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEnN7QnoQoG72upUfo5qM118W2lxoFAmbfOr4ACgkQ5qM118W2 lxoTGQ//SKoaiZwbtWZtEjYWUJPxGL5gbidmqdmtT9b0ttBK+ufRRbRQXeuXv+pY KlKE3YxS8aWbW+YPvtQ7Ly6W4KoJ49esZYnFRMwnLnOpJY9KXtWe0ej+ohQIqm0g R/7MFx9YiKsO+oNI3Bk8Flfkdhh2RCSECO/i5V0oZIkZHy3ceeM/EAlMXy2slC7Z jcDLKkHsDSTkNhuCiNFwR8t04y2sZhYXPDC3xG/9FzO8dlstj6Kj7L0E7uceb3yP 9LlmnQB8AAXQ/ZpJ82Roe72ORGuL5xwUPDpEPKnM2090h6skIA9cpIn4BpRpg/6S rrZb/fSIjLlE8YnkA39kKnMS1SW5O2EXSDtXCzEkZI40vGHIJiVY2j+mELqHiWLf 8MLVC0qW2DvOMA28ZAipQ2gG9txxuArLBD/Zlhtlzn4KeP8m1Dnnv1kkL8z8+H+6 18zM9lcE4xK8ET+9yao5yNpYinhwEHQnekeevMBJPrI/5SQxkb53u+FXeg1eGAbK IewcLlpxun/IwL8D0NwY2/1EVlemupEed9geHDBIjM9gPmBG/zYJdRvh2aLUXcti C5nxXAXUknXYAyUwT2kvplLyj1yZheA9nDonIVI9GY1nyZmzWsT0D7BSoOGxw+6H 4nhcsQfHpEVQvCfY9G2wOvmqiZEkbFDho/3o7hebowkFljXXcKU= =IC32 -----END PGP SIGNATURE----- Merge tag 'v1.9.4' into multiport 1.9.4 Release
90 lines
1.9 KiB
Go
90 lines
1.9 KiB
Go
package firewall
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
mathrand "math/rand"
|
|
"net/netip"
|
|
)
|
|
|
|
type m map[string]interface{}
|
|
|
|
const (
|
|
ProtoAny = 0 // When we want to handle HOPOPT (0) we can change this, if ever
|
|
ProtoTCP = 6
|
|
ProtoUDP = 17
|
|
ProtoICMP = 1
|
|
|
|
PortAny = 0 // Special value for matching `port: any`
|
|
PortFragment = -1 // Special value for matching `port: fragment`
|
|
)
|
|
|
|
type Packet struct {
|
|
LocalIP netip.Addr
|
|
RemoteIP netip.Addr
|
|
LocalPort uint16
|
|
RemotePort uint16
|
|
Protocol uint8
|
|
Fragment bool
|
|
}
|
|
|
|
func (fp *Packet) Copy() *Packet {
|
|
return &Packet{
|
|
LocalIP: fp.LocalIP,
|
|
RemoteIP: fp.RemoteIP,
|
|
LocalPort: fp.LocalPort,
|
|
RemotePort: fp.RemotePort,
|
|
Protocol: fp.Protocol,
|
|
Fragment: fp.Fragment,
|
|
}
|
|
}
|
|
|
|
func (fp Packet) MarshalJSON() ([]byte, error) {
|
|
var proto string
|
|
switch fp.Protocol {
|
|
case ProtoTCP:
|
|
proto = "tcp"
|
|
case ProtoICMP:
|
|
proto = "icmp"
|
|
case ProtoUDP:
|
|
proto = "udp"
|
|
default:
|
|
proto = fmt.Sprintf("unknown %v", fp.Protocol)
|
|
}
|
|
return json.Marshal(m{
|
|
"LocalIP": fp.LocalIP.String(),
|
|
"RemoteIP": fp.RemoteIP.String(),
|
|
"LocalPort": fp.LocalPort,
|
|
"RemotePort": fp.RemotePort,
|
|
"Protocol": proto,
|
|
"Fragment": fp.Fragment,
|
|
})
|
|
}
|
|
|
|
// UDPSendPort calculates the UDP port to send from when using multiport mode.
|
|
// The result will be from [0, numBuckets)
|
|
func (fp Packet) UDPSendPort(numBuckets int) uint16 {
|
|
if numBuckets <= 1 {
|
|
return 0
|
|
}
|
|
|
|
// If there is no port (like an ICMP packet), pick a random UDP send port
|
|
if fp.LocalPort == 0 {
|
|
return uint16(mathrand.Intn(numBuckets))
|
|
}
|
|
|
|
// A decent enough 32bit hash function
|
|
// Prospecting for Hash Functions
|
|
// - https://nullprogram.com/blog/2018/07/31/
|
|
// - https://github.com/skeeto/hash-prospector
|
|
// [16 21f0aaad 15 d35a2d97 15] = 0.10760229515479501
|
|
x := (uint32(fp.LocalPort) << 16) | uint32(fp.RemotePort)
|
|
x ^= x >> 16
|
|
x *= 0x21f0aaad
|
|
x ^= x >> 15
|
|
x *= 0xd35a2d97
|
|
x ^= x >> 15
|
|
|
|
return uint16(x) % uint16(numBuckets)
|
|
}
|