mirror of
https://github.com/tim-beatham/smegmesh.git
synced 2025-01-07 22:08:53 +01:00
24-keepalive-holepunch
Added the ability to hole punch NAT
This commit is contained in:
parent
6e201ebaf5
commit
7b939e0468
46
pkg/lib/hashing.go
Normal file
46
pkg/lib/hashing.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"hash/fnv"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
type consistentHashRecord[V any] struct {
|
||||||
|
record V
|
||||||
|
value int
|
||||||
|
}
|
||||||
|
|
||||||
|
func HashString(value string) int {
|
||||||
|
f := fnv.New32a()
|
||||||
|
f.Write([]byte(value))
|
||||||
|
return int(f.Sum32())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConsistentHash implementation. Traverse the values until we find a key
|
||||||
|
// less than ours.
|
||||||
|
func ConsistentHash[V any](values []V, client V, keyFunc func(V) int) V {
|
||||||
|
if len(values) == 0 {
|
||||||
|
panic("values is empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
vs := Map(values, func(v V) consistentHashRecord[V] {
|
||||||
|
return consistentHashRecord[V]{
|
||||||
|
v,
|
||||||
|
keyFunc(v),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
sort.SliceStable(vs, func(i, j int) bool {
|
||||||
|
return vs[i].value < vs[j].value
|
||||||
|
})
|
||||||
|
|
||||||
|
ourKey := keyFunc(client)
|
||||||
|
|
||||||
|
for _, record := range vs {
|
||||||
|
if ourKey < record.value {
|
||||||
|
return record.record
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return vs[0].record
|
||||||
|
}
|
@ -2,7 +2,6 @@ package mesh
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/fnv"
|
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -88,14 +87,16 @@ func (m *WgMeshConfigApplyer) updateWgConf(mesh MeshProvider) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, n := range nodes {
|
for _, n := range nodes {
|
||||||
|
if NodeEquals(n, self) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if n.GetType() == conf.CLIENT_ROLE && len(peers) > 0 {
|
if n.GetType() == conf.CLIENT_ROLE && len(peers) > 0 {
|
||||||
a := fnv.New32a()
|
peer := lib.ConsistentHash(peers, n, func(mn MeshNode) int {
|
||||||
a.Write([]byte(n.GetHostEndpoint()))
|
return lib.HashString(mn.GetWgHost().String())
|
||||||
sum := a.Sum32()
|
})
|
||||||
|
|
||||||
responsiblePeer := peers[int(sum)%len(peers)]
|
if !NodeEquals(peer, self) {
|
||||||
|
|
||||||
if responsiblePeer.GetHostEndpoint() != self.GetHostEndpoint() {
|
|
||||||
dev, err := mesh.GetDevice()
|
dev, err := mesh.GetDevice()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -103,7 +104,7 @@ func (m *WgMeshConfigApplyer) updateWgConf(mesh MeshProvider) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rtnl.AddRoute(dev.Name, lib.Route{
|
rtnl.AddRoute(dev.Name, lib.Route{
|
||||||
Gateway: responsiblePeer.GetWgHost().IP,
|
Gateway: peer.GetWgHost().IP,
|
||||||
Destination: *n.GetWgHost(),
|
Destination: *n.GetWgHost(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user