WIP
This commit is contained in:
@@ -21,6 +21,7 @@ type HubPoller struct {
|
||||
vpnNet netip.Prefix
|
||||
hubURL string
|
||||
apiKey string
|
||||
statePath string // where the network state cache is persisted
|
||||
addCh chan<- HubPeer
|
||||
removeCh chan<- wgtypes.Key
|
||||
known map[wgtypes.Key]int64 // pubKey → last seen version
|
||||
@@ -30,6 +31,7 @@ func NewHubPoller(
|
||||
selfVPNIP netip.Addr,
|
||||
vpnNet netip.Prefix,
|
||||
hubURL, apiKey string,
|
||||
statePath string,
|
||||
addCh chan<- HubPeer,
|
||||
removeCh chan<- wgtypes.Key,
|
||||
) (*HubPoller, error) {
|
||||
@@ -44,6 +46,7 @@ func NewHubPoller(
|
||||
vpnNet: vpnNet,
|
||||
hubURL: u.String(),
|
||||
apiKey: apiKey,
|
||||
statePath: statePath,
|
||||
addCh: addCh,
|
||||
removeCh: removeCh,
|
||||
known: make(map[wgtypes.Key]int64),
|
||||
@@ -51,6 +54,14 @@ func NewHubPoller(
|
||||
}
|
||||
|
||||
func (hp *HubPoller) Run() {
|
||||
// Prime from the on-disk cache before reaching the hub, so the peer
|
||||
// configures WireGuard from its last known state even if the hub is down.
|
||||
// known starts empty, so this emits every cached peer as an add and seeds
|
||||
// the version map; the first real poll then emits only deltas.
|
||||
if state, err := loadNetworkState(hp.statePath); err == nil {
|
||||
hp.apply(state)
|
||||
}
|
||||
|
||||
hp.poll()
|
||||
for range time.Tick(hubPollInterval) {
|
||||
hp.poll()
|
||||
@@ -90,10 +101,19 @@ func (hp *HubPoller) poll() {
|
||||
return
|
||||
}
|
||||
|
||||
hp.apply(state)
|
||||
// Persist only when the state actually changed, to avoid needless writes
|
||||
// on every poll.
|
||||
if hp.apply(state) {
|
||||
if err := saveNetworkState(hp.statePath, state); err != nil {
|
||||
log.Printf("[HubPoller] save state: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (hp *HubPoller) apply(state m.NetworkState) {
|
||||
// apply diffs state against the known versions, emitting add events for new or
|
||||
// changed peers and remove events for peers that disappeared. It returns true
|
||||
// if anything changed.
|
||||
func (hp *HubPoller) apply(state m.NetworkState) (changed bool) {
|
||||
seen := make(map[wgtypes.Key]struct{}, len(hp.known))
|
||||
|
||||
netAddr := hp.vpnNet.Addr().As4()
|
||||
@@ -122,14 +142,18 @@ func (hp *HubPoller) apply(state m.NetworkState) {
|
||||
}
|
||||
hp.known[pubKey] = p.Version
|
||||
hp.addCh <- hubPeerFrom(pubKey, vpnIP, p)
|
||||
changed = true
|
||||
}
|
||||
|
||||
for key := range hp.known {
|
||||
if _, ok := seen[key]; !ok {
|
||||
delete(hp.known, key)
|
||||
hp.removeCh <- key
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
|
||||
return changed
|
||||
}
|
||||
|
||||
func hubPeerFrom(pubKey wgtypes.Key, vpnIP netip.Addr, p *m.Peer) HubPeer {
|
||||
|
||||
Reference in New Issue
Block a user