mirror of
https://github.com/fosrl/newt.git
synced 2026-08-31 03:01:28 +02:00
Support reliable SECONDARY address adding
This commit is contained in:
@@ -184,7 +184,9 @@ func AddSecondaryAddress(interfaceName string, addr string) error {
|
||||
}
|
||||
|
||||
mask := net.IP(ipNet.Mask).String()
|
||||
AddIPv4Address(ip.String(), mask)
|
||||
if err := AddIPv4Address(ip.String(), mask); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if interfaceName == "" {
|
||||
return nil
|
||||
|
||||
@@ -2,6 +2,7 @@ package network
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/fosrl/newt/logger"
|
||||
@@ -86,14 +87,24 @@ func SetIPv4Settings(addresses []string, subnetMasks []string) {
|
||||
// exposed to mobile (iOS/Android) packet-tunnel providers, which read the
|
||||
// full IPv4Addresses/IPv4SubnetMasks arrays (not just the first entry) and
|
||||
// re-apply them on every settings poll.
|
||||
func AddIPv4Address(address string, subnetMask string) {
|
||||
//
|
||||
// It requires a primary address to already be set (via SetIPv4Settings,
|
||||
// i.e. ConfigureInterface) and refuses to add otherwise: on mobile
|
||||
// platforms, array order is what determines which address the OS treats as
|
||||
// primary, so appending to an empty list would silently make this
|
||||
// "additional" address the primary one instead.
|
||||
func AddIPv4Address(address string, subnetMask string) error {
|
||||
networkSettingsMutex.Lock()
|
||||
defer networkSettingsMutex.Unlock()
|
||||
|
||||
if len(networkSettings.IPv4Addresses) == 0 {
|
||||
return fmt.Errorf("cannot add secondary IPv4 address %s: no primary address configured yet", address)
|
||||
}
|
||||
|
||||
for _, a := range networkSettings.IPv4Addresses {
|
||||
if a == address {
|
||||
logger.Info("IPv4 address already exists: %s", address)
|
||||
return
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,6 +112,7 @@ func AddIPv4Address(address string, subnetMask string) {
|
||||
networkSettings.IPv4SubnetMasks = append(networkSettings.IPv4SubnetMasks, subnetMask)
|
||||
incrementor++
|
||||
logger.Info("Added IPv4 address: %s/%s", address, subnetMask)
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveIPv4Address removes a previously added secondary IPv4 address.
|
||||
|
||||
32
network/settings_test.go
Normal file
32
network/settings_test.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package network
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestAddIPv4AddressRequiresPrimary(t *testing.T) {
|
||||
ClearNetworkSettings()
|
||||
defer ClearNetworkSettings()
|
||||
|
||||
if err := AddIPv4Address("10.10.0.5", "255.255.255.255"); err == nil {
|
||||
t.Fatal("expected an error adding a secondary address before any primary address is set")
|
||||
}
|
||||
if got := GetSettings().IPv4Addresses; len(got) != 0 {
|
||||
t.Errorf("IPv4Addresses = %v, want empty after a rejected add", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddIPv4AddressAfterPrimarySucceeds(t *testing.T) {
|
||||
ClearNetworkSettings()
|
||||
defer ClearNetworkSettings()
|
||||
|
||||
SetIPv4Settings([]string{"10.10.0.1"}, []string{"255.255.255.0"})
|
||||
|
||||
if err := AddIPv4Address("10.10.0.5", "255.255.255.255"); err != nil {
|
||||
t.Fatalf("unexpected error adding secondary address: %v", err)
|
||||
}
|
||||
|
||||
got := GetSettings().IPv4Addresses
|
||||
want := []string{"10.10.0.1", "10.10.0.5"}
|
||||
if len(got) != len(want) || got[0] != want[0] || got[1] != want[1] {
|
||||
t.Errorf("IPv4Addresses = %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user