Removed peer editing, cleanup
This commit is contained in:
@@ -24,7 +24,7 @@ type HubPoller struct {
|
||||
statePath string // where the network state cache is persisted
|
||||
addCh chan<- m.Peer
|
||||
removeCh chan<- wgtypes.Key
|
||||
known map[wgtypes.Key]int64 // pubKey → last seen version
|
||||
known map[wgtypes.Key]struct{} // pubKeys currently configured
|
||||
}
|
||||
|
||||
func NewHubPoller(
|
||||
@@ -49,15 +49,15 @@ func NewHubPoller(
|
||||
statePath: statePath,
|
||||
addCh: addCh,
|
||||
removeCh: removeCh,
|
||||
known: make(map[wgtypes.Key]int64),
|
||||
known: make(map[wgtypes.Key]struct{}),
|
||||
}, nil
|
||||
}
|
||||
|
||||
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.
|
||||
// known starts empty, so this emits every cached peer as an add; the first
|
||||
// real poll then emits only deltas (adds for new peers, removes for gone).
|
||||
if state, err := loadNetworkState(hp.statePath); err == nil {
|
||||
hp.apply(state)
|
||||
}
|
||||
@@ -110,9 +110,10 @@ func (hp *HubPoller) poll() {
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
// apply diffs state against the set of known peers, emitting an add for each
|
||||
// newly-seen peer and a remove for each that disappeared. It returns true if
|
||||
// anything changed. A peer's config is immutable under a stable WG key (the hub
|
||||
// has no peer-edit path), so a key already in known needs no re-emit.
|
||||
func (hp *HubPoller) apply(state m.NetworkState) (changed bool) {
|
||||
seen := make(map[wgtypes.Key]struct{}, len(hp.known))
|
||||
|
||||
@@ -132,10 +133,10 @@ func (hp *HubPoller) apply(state m.NetworkState) (changed bool) {
|
||||
|
||||
seen[p.WGPubKey] = struct{}{}
|
||||
|
||||
if v, ok := hp.known[p.WGPubKey]; ok && v == p.Version {
|
||||
if _, ok := hp.known[p.WGPubKey]; ok {
|
||||
continue
|
||||
}
|
||||
hp.known[p.WGPubKey] = p.Version
|
||||
hp.known[p.WGPubKey] = struct{}{}
|
||||
hp.addCh <- p
|
||||
changed = true
|
||||
}
|
||||
|
||||
@@ -18,15 +18,14 @@ func testPoller(t *testing.T) (*HubPoller, chan m.Peer, chan wgtypes.Key) {
|
||||
vpnNet: netip.MustParsePrefix("10.0.0.0/24"),
|
||||
addCh: addCh,
|
||||
removeCh: removeCh,
|
||||
known: make(map[wgtypes.Key]int64),
|
||||
known: make(map[wgtypes.Key]struct{}),
|
||||
}
|
||||
return hp, addCh, removeCh
|
||||
}
|
||||
|
||||
func stateWith(key wgtypes.Key, peerIP byte, version int64) m.NetworkState {
|
||||
func stateWith(key wgtypes.Key, peerIP byte) m.NetworkState {
|
||||
return m.NetworkState{Peers: []m.Peer{{
|
||||
PeerIP: peerIP,
|
||||
Version: version,
|
||||
WGPubKey: key,
|
||||
}}}
|
||||
}
|
||||
@@ -35,7 +34,7 @@ func TestApply_EmitsAddsAndReportsChange(t *testing.T) {
|
||||
hp, addCh, _ := testPoller(t)
|
||||
key := mustKey(t)
|
||||
|
||||
if changed := hp.apply(stateWith(key, 2, 1)); !changed {
|
||||
if changed := hp.apply(stateWith(key, 2)); !changed {
|
||||
t.Fatal("expected changed=true on first apply")
|
||||
}
|
||||
if len(addCh) != 1 {
|
||||
@@ -46,41 +45,26 @@ func TestApply_EmitsAddsAndReportsChange(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestApply_NoChangeWhenVersionSame(t *testing.T) {
|
||||
func TestApply_NoChangeWhenKnown(t *testing.T) {
|
||||
hp, addCh, _ := testPoller(t)
|
||||
key := mustKey(t)
|
||||
|
||||
hp.apply(stateWith(key, 2, 1))
|
||||
hp.apply(stateWith(key, 2))
|
||||
<-addCh // drain initial add
|
||||
|
||||
if changed := hp.apply(stateWith(key, 2, 1)); changed {
|
||||
t.Fatal("expected changed=false when version unchanged")
|
||||
if changed := hp.apply(stateWith(key, 2)); changed {
|
||||
t.Fatal("expected changed=false when peer already known")
|
||||
}
|
||||
if len(addCh) != 0 {
|
||||
t.Fatalf("expected no re-emit, got %d adds", len(addCh))
|
||||
}
|
||||
}
|
||||
|
||||
func TestApply_ReEmitsOnVersionBump(t *testing.T) {
|
||||
hp, addCh, _ := testPoller(t)
|
||||
key := mustKey(t)
|
||||
|
||||
hp.apply(stateWith(key, 2, 1))
|
||||
<-addCh
|
||||
|
||||
if changed := hp.apply(stateWith(key, 2, 2)); !changed {
|
||||
t.Fatal("expected changed=true on version bump")
|
||||
}
|
||||
if len(addCh) != 1 {
|
||||
t.Fatalf("expected 1 re-emit, got %d", len(addCh))
|
||||
}
|
||||
}
|
||||
|
||||
func TestApply_RemovesVanishedPeer(t *testing.T) {
|
||||
hp, addCh, removeCh := testPoller(t)
|
||||
key := mustKey(t)
|
||||
|
||||
hp.apply(stateWith(key, 2, 1))
|
||||
hp.apply(stateWith(key, 2))
|
||||
<-addCh
|
||||
|
||||
// Empty state: the peer is gone.
|
||||
|
||||
@@ -18,7 +18,6 @@ func TestNetworkState_RoundTrip(t *testing.T) {
|
||||
state := m.NetworkState{Peers: []m.Peer{
|
||||
{
|
||||
PeerIP: 1,
|
||||
Version: 7,
|
||||
Name: "hub",
|
||||
Addr4: netip.MustParseAddr("10.11.12.1"),
|
||||
Port: 51820,
|
||||
@@ -28,7 +27,6 @@ func TestNetworkState_RoundTrip(t *testing.T) {
|
||||
},
|
||||
{
|
||||
PeerIP: 10,
|
||||
Version: 3,
|
||||
Name: "laptop",
|
||||
Addr4: netip.MustParseAddr("10.11.12.10"),
|
||||
Port: 51820,
|
||||
|
||||
@@ -25,8 +25,8 @@ func (a *App) onAddPeer(p m.Peer) {
|
||||
Name: p.Name,
|
||||
IsRelay: p.Relay,
|
||||
IsPublic: p.IsPublic(),
|
||||
Endpoint4: p.Endpoint4(),
|
||||
Endpoint6: p.Endpoint6(),
|
||||
EndpointV4: p.Endpoint4(),
|
||||
EndpointV6: p.Endpoint6(),
|
||||
RTT: time.Duration(math.MaxInt64) * time.Nanosecond,
|
||||
Role: roleFor(a.isPublic, a.vpnIP, p.IsPublic(), vpnIP),
|
||||
SignPubKey: p.SignPubKey,
|
||||
|
||||
@@ -280,7 +280,7 @@ func TestSwitchActiveRelay(t *testing.T) {
|
||||
t.Errorf("call[0]: got %v, want AddDirect with ep1", dev.Calls[0])
|
||||
}
|
||||
dev.AssertSetRelay(t, 1, dev.Calls[1].PubKey, ep2, a.vpnNet)
|
||||
if a.relay == nil || a.relay.Endpoint4 != ep2 {
|
||||
if a.relay == nil || a.relay.EndpointV4 != ep2 {
|
||||
t.Error("relay should be the backup peer")
|
||||
}
|
||||
},
|
||||
|
||||
@@ -24,8 +24,8 @@ type Peer struct {
|
||||
Name string // Human-readable DNS label.
|
||||
IsRelay bool // Peer is a relay.
|
||||
IsPublic bool // Peer has a public IP.
|
||||
Endpoint4 netip.AddrPort // Reported IPv4 endpoint.
|
||||
Endpoint6 netip.AddrPort // Reported IPv6 endpoint.
|
||||
EndpointV4 netip.AddrPort // Reported IPv4 endpoint.
|
||||
EndpointV6 netip.AddrPort // Reported IPv6 endpoint.
|
||||
RTT time.Duration // Round-trip time.
|
||||
State PeerState // Current routing state; updated on each devXxx call.
|
||||
Role control.Role // Client initiates pings; server responds.
|
||||
@@ -62,14 +62,14 @@ func (p *Peer) CanRelay() bool {
|
||||
}
|
||||
|
||||
func (p *Peer) PreferredEndpoint() netip.AddrPort {
|
||||
return preferredEndpoint(p.Endpoint4, p.Endpoint6)
|
||||
return preferredEndpoint(p.EndpointV4, p.EndpointV6)
|
||||
}
|
||||
|
||||
func (p *Peer) UpdateEndpoints(v4, v6 netip.AddrPort) {
|
||||
if v4.IsValid() {
|
||||
p.Endpoint4 = v4
|
||||
p.EndpointV4 = v4
|
||||
}
|
||||
if v6.IsValid() {
|
||||
p.Endpoint6 = v6
|
||||
p.EndpointV6 = v6
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user