88 "math/bits"
99 "net"
1010 "net/netip"
11- "strconv"
1211 "strings"
1312 "syscall"
1413
@@ -17,6 +16,7 @@ import (
1716 "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
1817 "tailscale.com/net/interfaces"
1918 "tailscale.com/net/netmon"
19+ "tailscale.com/net/tsaddr"
2020 "tailscale.com/types/logger"
2121)
2222
@@ -31,17 +31,6 @@ func interfaceIndex(iface *winipcfg.IPAdapterAddresses) uint32 {
3131 return iface .IfIndex
3232}
3333
34- // getBestInterface can be swapped out in tests.
35- var getBestInterface func (addr windows.Sockaddr , idx * uint32 ) error = windows .GetBestInterfaceEx
36-
37- // isInterfaceCoderInterface can be swapped out in tests.
38- var isInterfaceCoderInterface func (int ) bool = isInterfaceCoderInterfaceDefault
39-
40- func isInterfaceCoderInterfaceDefault (idx int ) bool {
41- _ , tsif , err := interfaces .Coder ()
42- return err == nil && tsif != nil && tsif .Index == idx
43- }
44-
4534func control (logf logger.Logf , netMon * netmon.Monitor ) func (network , address string , c syscall.RawConn ) error {
4635 return func (network , address string , c syscall.RawConn ) error {
4736 return controlLogf (logf , netMon , network , address , c )
@@ -98,30 +87,17 @@ func shouldBindToDefaultInterface(logf logger.Logf, address string) bool {
9887 }
9988
10089 if coderSoftIsolation .Load () {
101- sockAddr , err := getSockAddr (address )
90+ addr , err := getAddr (address )
10291 if err != nil {
103- logf ("[unexpected] netns: Coder soft isolation: error getting sockaddr for %q, binding to default: %v" , address , err )
92+ logf ("[unexpected] netns: Coder soft isolation: error getting addr for %q, binding to default: %v" , address , err )
10493 return true
10594 }
106- if sockAddr == nil {
107- // Unspecified addresses should not be bound to any interface.
95+ if ! addr .IsValid () || addr .IsUnspecified () {
96+ // Invalid or unspecified addresses should not be bound to any
97+ // interface.
10898 return false
10999 }
110-
111- // Ask Windows to find the best interface for this address by consulting
112- // the routing table.
113- //
114- // On macOS this value gets cached, but on Windows we don't need to
115- // because this API is very fast and doesn't require opening an AF_ROUTE
116- // socket.
117- var idx uint32
118- err = getBestInterface (sockAddr , & idx )
119- if err != nil {
120- logf ("[unexpected] netns: Coder soft isolation: error getting best interface, binding to default: %v" , err )
121- return true
122- }
123-
124- if isInterfaceCoderInterface (int (idx )) {
100+ if tsaddr .IsCoderIP (addr ) {
125101 logf ("[unexpected] netns: Coder soft isolation: detected socket destined for Coder interface, binding to default" )
126102 return true
127103 }
@@ -187,47 +163,31 @@ func nativeToBigEndian(i uint32) uint32 {
187163 return bits .ReverseBytes32 (i )
188164}
189165
190- // getSockAddr returns the Windows sockaddr for the given address, or nil if
191- // the address is not specified.
192- func getSockAddr (address string ) (windows. Sockaddr , error ) {
193- host , port , err := net .SplitHostPort (address )
166+ // getAddr returns the netip.Addr for the given address, or an invalid address
167+ // if the address is not specified. Use addr.IsValid() to check for this .
168+ func getAddr (address string ) (netip. Addr , error ) {
169+ host , _ , err := net .SplitHostPort (address )
194170 if err != nil {
195- return nil , fmt .Errorf ("invalid address %q: %w" , address , err )
171+ return netip. Addr {} , fmt .Errorf ("invalid address %q: %w" , address , err )
196172 }
197173 if host == "" {
198174 // netip.ParseAddr("") will fail
199- return nil , nil
175+ return netip. Addr {} , nil
200176 }
201177
202178 addr , err := netip .ParseAddr (host )
203179 if err != nil {
204- return nil , fmt .Errorf ("invalid address %q: %w" , address , err )
180+ return netip. Addr {} , fmt .Errorf ("invalid address %q: %w" , address , err )
205181 }
206182 if addr .Zone () != "" {
207183 // Addresses with zones *can* be represented as a Sockaddr with extra
208184 // effort, but we don't use or support them currently.
209- return nil , fmt .Errorf ("invalid address %q, has zone: %w" , address , err )
185+ return netip. Addr {} , fmt .Errorf ("invalid address %q, has zone: %w" , address , err )
210186 }
211187 if addr .IsUnspecified () {
212188 // This covers the cases of 0.0.0.0 and [::].
213- return nil , nil
214- }
215-
216- portInt , err := strconv .ParseUint (port , 10 , 16 )
217- if err != nil {
218- return nil , fmt .Errorf ("invalid port %q: %w" , port , err )
189+ return netip.Addr {}, nil
219190 }
220191
221- if addr .Is4 () {
222- return & windows.SockaddrInet4 {
223- Port : int (portInt ), // nolint:gosec // portInt is always in range
224- Addr : addr .As4 (),
225- }, nil
226- } else if addr .Is6 () {
227- return & windows.SockaddrInet6 {
228- Port : int (portInt ), // nolint:gosec // portInt is always in range
229- Addr : addr .As16 (),
230- }, nil
231- }
232- return nil , fmt .Errorf ("invalid address %q, is not IPv4 or IPv6: %w" , address , err )
192+ return addr , nil
233193}
0 commit comments