Browse Source

net/netmon: handle net.IPAddr types during interface address parsing (#17523)

updates tailscale/tailscale#16836

Android's altNetInterfaces implementation now returns net.IPAddr
types which netmon wasn't handling.

Signed-off-by: Jonathan Nobels <[email protected]>
Jonathan Nobels 5 months ago
parent
commit
8e98ecb5f7
2 changed files with 48 additions and 0 deletions
  1. 40 0
      net/netmon/netmon_test.go
  2. 8 0
      net/netmon/state.go

+ 40 - 0
net/netmon/netmon_test.go

@@ -7,6 +7,7 @@ import (
 	"flag"
 	"net"
 	"net/netip"
+	"reflect"
 	"sync/atomic"
 	"testing"
 	"time"
@@ -267,6 +268,45 @@ func TestIsMajorChangeFrom(t *testing.T) {
 		})
 	}
 }
+func TestForeachInterface(t *testing.T) {
+	tests := []struct {
+		name  string
+		addrs []net.Addr
+		want  []string
+	}{
+		{
+			name: "Mixed_IPv4_and_IPv6",
+			addrs: []net.Addr{
+				&net.IPNet{IP: net.IPv4(1, 2, 3, 4), Mask: net.CIDRMask(24, 32)},
+				&net.IPAddr{IP: net.IP{5, 6, 7, 8}, Zone: ""},
+				&net.IPNet{IP: net.ParseIP("2001:db8::1"), Mask: net.CIDRMask(64, 128)},
+				&net.IPAddr{IP: net.ParseIP("2001:db8::2"), Zone: ""},
+			},
+			want: []string{"1.2.3.4", "5.6.7.8", "2001:db8::1", "2001:db8::2"},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			var got []string
+			ifaces := InterfaceList{
+				{
+					Interface: &net.Interface{Name: "eth0"},
+					AltAddrs:  tt.addrs,
+				},
+			}
+			ifaces.ForeachInterface(func(iface Interface, prefixes []netip.Prefix) {
+				for _, prefix := range prefixes {
+					ip := prefix.Addr()
+					got = append(got, ip.String())
+				}
+			})
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("got %q, want %q", got, tt.want)
+			}
+		})
+	}
+}
 
 type testOSMon struct {
 	osMon

+ 8 - 0
net/netmon/state.go

@@ -183,6 +183,10 @@ func (ifaces InterfaceList) ForeachInterfaceAddress(fn func(Interface, netip.Pre
 				if pfx, ok := netaddr.FromStdIPNet(v); ok {
 					fn(iface, pfx)
 				}
+			case *net.IPAddr:
+				if ip, ok := netip.AddrFromSlice(v.IP); ok {
+					fn(iface, netip.PrefixFrom(ip, ip.BitLen()))
+				}
 			}
 		}
 	}
@@ -215,6 +219,10 @@ func (ifaces InterfaceList) ForeachInterface(fn func(Interface, []netip.Prefix))
 				if pfx, ok := netaddr.FromStdIPNet(v); ok {
 					pfxs = append(pfxs, pfx)
 				}
+			case *net.IPAddr:
+				if ip, ok := netip.AddrFromSlice(v.IP); ok {
+					pfxs = append(pfxs, netip.PrefixFrom(ip, ip.BitLen()))
+				}
 			}
 		}
 		sort.Slice(pfxs, func(i, j int) bool {