mirror of
https://github.com/slackhq/nebula.git
synced 2025-11-09 00:43:57 +01:00
Some checks failed
gofmt / Run gofmt (push) Successful in 27s
smoke-extra / Run extra smoke tests (push) Failing after 18s
smoke / Run multi node smoke test (push) Failing after 1m26s
Build and test / Build all and test on ubuntu-linux (push) Failing after 21m43s
Build and test / Build and test on linux with boringcrypto (push) Failing after 3m45s
Build and test / Build and test on linux with pkcs11 (push) Failing after 2m59s
Build and test / Build and test on macos-latest (push) Has been cancelled
Build and test / Build and test on windows-latest (push) Has been cancelled
40 lines
1.2 KiB
Go
40 lines
1.2 KiB
Go
package routing
|
|
|
|
import (
|
|
"net/netip"
|
|
|
|
"github.com/slackhq/nebula/firewall"
|
|
)
|
|
|
|
// Hashes the packet source and destination port and always returns a positive integer
|
|
// Based on 'Prospecting for Hash Functions'
|
|
// - https://nullprogram.com/blog/2018/07/31/
|
|
// - https://github.com/skeeto/hash-prospector
|
|
// [16 21f0aaad 15 d35a2d97 15] = 0.10760229515479501
|
|
func hashPacket(p *firewall.Packet) int {
|
|
x := (uint32(p.LocalPort) << 16) | uint32(p.RemotePort)
|
|
x ^= x >> 16
|
|
x *= 0x21f0aaad
|
|
x ^= x >> 15
|
|
x *= 0xd35a2d97
|
|
x ^= x >> 15
|
|
|
|
return int(x) & 0x7FFFFFFF
|
|
}
|
|
|
|
// For this function to work correctly it requires that the buckets for the gateways have been calculated
|
|
// If the contract is violated balancing will not work properly and the second return value will return false
|
|
func BalancePacket(fwPacket *firewall.Packet, gateways []Gateway) (netip.Addr, bool) {
|
|
hash := hashPacket(fwPacket)
|
|
|
|
for i := range gateways {
|
|
if hash <= gateways[i].BucketUpperBound() {
|
|
return gateways[i].Addr(), true
|
|
}
|
|
}
|
|
|
|
// If you land here then the buckets for the gateways are not properly calculated
|
|
// Fallback to random routing and let the caller know
|
|
return gateways[hash%len(gateways)].Addr(), false
|
|
}
|