Improve handling of allowed ips

This commit is contained in:
Owen
2025-12-03 15:50:00 -05:00
parent e898d4454f
commit 1a2a2e5453
3 changed files with 63 additions and 11 deletions

View File

@@ -786,12 +786,7 @@ func StartTunnel(config TunnelConfig) {
logger.Debug("Exit node %s already in holepunch rotation", exitNode.Endpoint)
}
// Start holepunching if not already running
if !holePunchManager.IsRunning() {
if err := holePunchManager.Start(); err != nil {
logger.Error("Failed to start holepunch manager: %v", err)
}
}
holePunchManager.ResetInterval() // start sending immediately again so we fill in the endpoint on the cloud
}
// Send handshake acknowledgment back to server with retry

View File

@@ -455,7 +455,7 @@ func (pm *PeerManager) addAllowedIp(siteId int, ip string) error {
// Only update WireGuard if we own this IP
if pm.allowedIPOwners[ip] == siteId {
if err := ConfigurePeer(pm.device, peer, pm.privateKey, pm.peerMonitor.IsPeerRelayed(peer.SiteId)); err != nil {
if err := AddAllowedIP(pm.device, peer.PublicKey, ip); err != nil {
return err
}
}
@@ -494,15 +494,30 @@ func (pm *PeerManager) removeAllowedIp(siteId int, cidr string) error {
// Release our claim and check if we need to promote another peer
newOwner, promoted := pm.releaseAllowedIP(siteId, cidr)
// Update WireGuard for this peer (to remove the IP from its config)
if err := ConfigurePeer(pm.device, peer, pm.privateKey, pm.peerMonitor.IsPeerRelayed(peer.SiteId)); err != nil {
// Build the list of IPs this peer currently owns for the replace operation
ownedIPs := pm.getOwnedAllowedIPs(siteId)
// Also include the server IP which is always owned
serverIP := strings.Split(peer.ServerIP, "/")[0] + "/32"
hasServerIP := false
for _, ip := range ownedIPs {
if ip == serverIP {
hasServerIP = true
break
}
}
if !hasServerIP {
ownedIPs = append([]string{serverIP}, ownedIPs...)
}
// Update WireGuard for this peer using replace_allowed_ips
if err := RemoveAllowedIP(pm.device, peer.PublicKey, ownedIPs); err != nil {
return err
}
// If another peer was promoted to owner, update their WireGuard config
// If another peer was promoted to owner, add the IP to their WireGuard config
if promoted && newOwner >= 0 {
if newOwnerPeer, exists := pm.peers[newOwner]; exists {
if err := ConfigurePeer(pm.device, newOwnerPeer, pm.privateKey, pm.peerMonitor.IsPeerRelayed(peer.SiteId)); err != nil {
if err := AddAllowedIP(pm.device, newOwnerPeer.PublicKey, cidr); err != nil {
logger.Error("Failed to promote peer %d for IP %s: %v", newOwner, cidr, err)
} else {
logger.Info("Promoted peer %d to owner of IP %s", newOwner, cidr)

View File

@@ -92,6 +92,48 @@ func RemovePeer(dev *device.Device, siteId int, publicKey string) error {
return nil
}
// AddAllowedIP adds a single allowed IP to an existing peer without reconfiguring the entire peer
func AddAllowedIP(dev *device.Device, publicKey string, allowedIP string) error {
var configBuilder strings.Builder
configBuilder.WriteString(fmt.Sprintf("public_key=%s\n", util.FixKey(publicKey)))
configBuilder.WriteString("update_only=true\n")
configBuilder.WriteString(fmt.Sprintf("allowed_ip=%s\n", allowedIP))
config := configBuilder.String()
logger.Debug("Adding allowed IP to peer with config: %s", config)
err := dev.IpcSet(config)
if err != nil {
return fmt.Errorf("failed to add allowed IP to WireGuard peer: %v", err)
}
return nil
}
// RemoveAllowedIP removes a single allowed IP from an existing peer by replacing the allowed IPs list
// This requires providing all the allowed IPs that should remain after removal
func RemoveAllowedIP(dev *device.Device, publicKey string, remainingAllowedIPs []string) error {
var configBuilder strings.Builder
configBuilder.WriteString(fmt.Sprintf("public_key=%s\n", util.FixKey(publicKey)))
configBuilder.WriteString("update_only=true\n")
configBuilder.WriteString("replace_allowed_ips=true\n")
// Add each remaining allowed IP
for _, allowedIP := range remainingAllowedIPs {
configBuilder.WriteString(fmt.Sprintf("allowed_ip=%s\n", allowedIP))
}
config := configBuilder.String()
logger.Debug("Removing allowed IP from peer with config: %s", config)
err := dev.IpcSet(config)
if err != nil {
return fmt.Errorf("failed to remove allowed IP from WireGuard peer: %v", err)
}
return nil
}
func formatEndpoint(endpoint string) string {
if strings.Contains(endpoint, ":") {
return endpoint