Skip to content

Commit 03328f2

Browse files
committed
handleInterfaceError handles interface lookup errors on mobile platforms.
1 parent ae405ad commit 03328f2

File tree

3 files changed

+43
-2
lines changed

3 files changed

+43
-2
lines changed

src/core/link_tcp.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,14 @@ func (l *linkTCP) dialerFor(dst *net.TCPAddr, sintf string) (*net.Dialer, error)
6969
dialer.Control = l.getControl(sintf)
7070
ief, err := net.InterfaceByName(sintf)
7171
if err != nil {
72-
return nil, fmt.Errorf("interface %q not found", sintf)
72+
return l.handleInterfaceError(err, sintf, dst, dialer)
7373
}
7474
if ief.Flags&net.FlagUp == 0 {
7575
return nil, fmt.Errorf("interface %q is not up", sintf)
7676
}
7777
addrs, err := ief.Addrs()
7878
if err != nil {
79-
return nil, fmt.Errorf("interface %q addresses not available: %w", sintf, err)
79+
return l.handleInterfaceError(err, sintf, dst, dialer)
8080
}
8181
for addrindex, addr := range addrs {
8282
src, _, err := net.ParseCIDR(addr.String())
@@ -104,6 +104,10 @@ func (l *linkTCP) dialerFor(dst *net.TCPAddr, sintf string) (*net.Dialer, error)
104104
}
105105
}
106106
if dialer.LocalAddr == nil {
107+
// Mobile platform workaround: proceed without source binding if link-local
108+
if dst.IP.IsLinkLocalUnicast() && dst.Zone != "" {
109+
return dialer, nil
110+
}
107111
return nil, fmt.Errorf("no suitable source address found on interface %q", sintf)
108112
}
109113
}

src/core/link_tcp_default.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//go:build !android && !ios
2+
3+
package core
4+
5+
import (
6+
"fmt"
7+
"net"
8+
)
9+
10+
// handleInterfaceError handles interface lookup errors on desktop platforms.
11+
// On desktop systems, InterfaceByName failure is a genuine error that should
12+
// be reported, as these platforms don't have the same restrictions as mobile.
13+
func (l *linkTCP) handleInterfaceError(err error, sintf string, dst *net.TCPAddr, dialer *net.Dialer) (*net.Dialer, error) {
14+
return nil, fmt.Errorf("interface %q not found: %w", sintf, err)
15+
}

src/core/link_tcp_mobile.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//go:build android || ios
2+
3+
package core
4+
5+
import (
6+
"fmt"
7+
"net"
8+
)
9+
10+
// handleInterfaceError handles interface lookup errors on mobile platforms.
11+
// On Android/iOS, InterfaceByName may fail due to permission restrictions
12+
// (SELinux on Android), but for link-local addresses with zone identifiers,
13+
// the zone is sufficient for routing and we can proceed without source binding.
14+
func (l *linkTCP) handleInterfaceError(err error, sintf string, dst *net.TCPAddr, dialer *net.Dialer) (*net.Dialer, error) {
15+
// For link-local addresses with zone set, we can proceed without binding
16+
// The zone identifier tells the kernel which interface to use
17+
if dst.IP.IsLinkLocalUnicast() && dst.Zone != "" {
18+
return dialer, nil
19+
}
20+
// For other cases, return the original error
21+
return nil, fmt.Errorf("interface %q not found: %w", sintf, err)
22+
}

0 commit comments

Comments
 (0)