|
|
|
@ -1,6 +1,7 @@
|
|
|
|
|
package zones |
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"fmt" |
|
|
|
|
"net/netip" |
|
|
|
|
|
|
|
|
|
"git.jpi.io/amery/jpictl/pkg/wireguard" |
|
|
|
@ -24,6 +25,73 @@ type RingInfo struct {
|
|
|
|
|
Address netip.Addr `toml:"address,omitempty"` |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Merge attempts to combine two RingInfo structs
|
|
|
|
|
func (ri *RingInfo) Merge(alter *RingInfo) error { |
|
|
|
|
switch { |
|
|
|
|
case ri.Ring != alter.Ring: |
|
|
|
|
// different ring
|
|
|
|
|
return fmt.Errorf("invalid %s: %v ≠ %v", "ring", ri.Ring, alter.Ring) |
|
|
|
|
case ri.Enabled != alter.Enabled: |
|
|
|
|
// different state
|
|
|
|
|
return fmt.Errorf("invalid %s: %v ≠ %v", "enabled", ri.Enabled, alter.Enabled) |
|
|
|
|
case !canMergeAddress(ri.Address, alter.Address): |
|
|
|
|
// different address
|
|
|
|
|
return fmt.Errorf("invalid %s: %v ≠ %v", "address", ri.Address, alter.Address) |
|
|
|
|
case !canMergeKeyPairs(ri.Keys, alter.Keys): |
|
|
|
|
// incompatible keypairs
|
|
|
|
|
return fmt.Errorf("invalid %s: %s ≠ %s", "keys", ri.Keys, alter.Keys) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
switch { |
|
|
|
|
case ri.Keys == nil: |
|
|
|
|
// assign keypair
|
|
|
|
|
ri.Keys = alter.Keys |
|
|
|
|
case alter.Keys != nil: |
|
|
|
|
// fill the gaps on our keypair
|
|
|
|
|
if ri.Keys.PrivateKey.IsZero() { |
|
|
|
|
ri.Keys.PrivateKey = alter.Keys.PrivateKey |
|
|
|
|
} |
|
|
|
|
if ri.Keys.PublicKey.IsZero() { |
|
|
|
|
ri.Keys.PublicKey = alter.Keys.PublicKey |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if addressEqual(ri.Address, netip.Addr{}) { |
|
|
|
|
// assign address
|
|
|
|
|
ri.Address = alter.Address |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func canMergeAddress(ip1, ip2 netip.Addr) bool { |
|
|
|
|
var zero netip.Addr |
|
|
|
|
|
|
|
|
|
switch { |
|
|
|
|
case addressEqual(ip1, zero) || addressEqual(ip2, zero) || addressEqual(ip1, ip2): |
|
|
|
|
return true |
|
|
|
|
default: |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func addressEqual(ip1, ip2 netip.Addr) bool { |
|
|
|
|
return ip1.Compare(ip2) == 0 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func canMergeKeyPairs(p1, p2 *wireguard.KeyPair) bool { |
|
|
|
|
switch { |
|
|
|
|
case p1 == nil || p2 == nil: |
|
|
|
|
return true |
|
|
|
|
case !p1.PrivateKey.IsZero() && !p2.PrivateKey.IsZero() && !p1.PrivateKey.Equal(p2.PrivateKey): |
|
|
|
|
return false |
|
|
|
|
case !p1.PublicKey.IsZero() && !p2.PublicKey.IsZero() && !p1.PublicKey.Equal(p2.PublicKey): |
|
|
|
|
return false |
|
|
|
|
default: |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// RingAddressEncoder provides encoder/decoder access for a particular
|
|
|
|
|
// Wireguard ring
|
|
|
|
|
type RingAddressEncoder struct { |
|
|
|
|