@@ -69,13 +69,24 @@ 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+ // On mobile platforms (Android/iOS), InterfaceByName may fail due to
73+ // permission restrictions (SELinux on Android), but for link-local
74+ // addresses with zone identifiers, the zone is sufficient for routing
75+ // and we can proceed without source binding
76+ if dst .IP .IsLinkLocalUnicast () && dst .Zone != "" {
77+ return dialer , nil
78+ }
7279 return nil , fmt .Errorf ("interface %q not found" , sintf )
7380 }
7481 if ief .Flags & net .FlagUp == 0 {
7582 return nil , fmt .Errorf ("interface %q is not up" , sintf )
7683 }
7784 addrs , err := ief .Addrs ()
7885 if err != nil {
86+ // Same mobile platform handling for address lookup failures
87+ if dst .IP .IsLinkLocalUnicast () && dst .Zone != "" {
88+ return dialer , nil
89+ }
7990 return nil , fmt .Errorf ("interface %q addresses not available: %w" , sintf , err )
8091 }
8192 for addrindex , addr := range addrs {
@@ -104,6 +115,10 @@ func (l *linkTCP) dialerFor(dst *net.TCPAddr, sintf string) (*net.Dialer, error)
104115 }
105116 }
106117 if dialer .LocalAddr == nil {
118+ // Proceed without source binding if link-local
119+ if dst .IP .IsLinkLocalUnicast () && dst .Zone != "" {
120+ return dialer , nil
121+ }
107122 return nil , fmt .Errorf ("no suitable source address found on interface %q" , sintf )
108123 }
109124 }
0 commit comments