@@ -71,7 +71,7 @@ typedef struct tport_nat_s tport_nat_t;
7171#include  <sofia-sip/rbtree.h> 
7272
7373#include  "tport_internal.h" 
74- #if  defined (__linux__ )
74+ #if  HAVE_GETIFADDRS   &&   defined (__linux__ )
7575#include  <ifaddrs.h> 
7676#if  HAVE_NET_IF_H 
7777#include  <net/if.h> 
@@ -520,6 +520,9 @@ tport_t *tport_tcreate(tp_stack_t *stack,
520520  tpp -> tpp_timeout  =  UINT_MAX ;
521521  tpp -> tpp_sigcomp_lifetime  =  UINT_MAX ;
522522  tpp -> tpp_socket_keepalive  =  30 ;
523+   #if  defined (__linux__ )
524+   tpp -> tpp_socket_bind_ifc  =  0 ;
525+   #endif 
523526  tpp -> tpp_keepalive  =  0 ;
524527  tpp -> tpp_pingpong  =  0 ;
525528  tpp -> tpp_pong2ping  =  0 ;
@@ -803,53 +806,51 @@ int tport_bind_socket(int socket,
803806    }
804807  }
805808#endif 
806- #if  defined(__linux__ )
807-   if  (tport_bind_socket_iface (socket , su , ai ) <  0 ) {
808-     return  -1 ;
809-   }
810- #endif 
809+ 
811810  return  0 ;
812811}
813812
814- #if  defined(__linux__ )
813+ #if  HAVE_GETIFADDRS   &&   defined  (__linux__ )
815814int  tport_bind_socket_iface (int  s ,
816-          su_sockaddr_t   * su ,
817- 		    su_addrinfo_t   * ai )
815+ 		     su_addrinfo_t   * ai ,
816+ 		    char   const   * * return_culprit )
818817{
818+   su_sockaddr_t  * su  =  (su_sockaddr_t  * )ai -> ai_addr ;
819819  struct  ifaddrs  * addrs , * iap ;
820820  struct  sockaddr_in  * sa ;
821821  struct  ifreq  ifr ;
822822  char  ipaddr [SU_ADDRSIZE  +  2 ];
823823
824-   getifaddrs (& addrs );
825-   for  (iap  =  addrs ; iap  !=  NULL ; iap  =  iap -> ifa_next ) {
826-     if  (iap -> ifa_addr  &&  (iap -> ifa_flags  &  IFF_UP ) &&  iap -> ifa_addr -> sa_family  ==  su -> su_family ) {
827-       sa  =  (struct  sockaddr_in  * )(iap -> ifa_addr );
828-       if (sa -> sin_addr .s_addr  ==  su -> su_sin .sin_addr .s_addr ) {
829-         memset (& ifr , 0 , sizeof (struct  ifreq ));
830-         strncpy (ifr .ifr_name , (char  const  * ) iap -> ifa_name , IFNAMSIZ );
831- 
832-         /* Assign socket to an already active access point (interface) */ 
833-         ioctl (s , SIOCSIFNAME , & ifr );
834-         if  (setsockopt (s , SOL_SOCKET , SO_BINDTODEVICE , (void  * )& ifr , sizeof (ifr )) <  0 ) {
835-             SU_DEBUG_3 (("socket: %d setsockopt(SO_BINDTODEVICE) error binding to ifc %s: %s\n" ,
836-                  s , ifr .ifr_name , su_strerror (su_errno ())));
837-             freeifaddrs (addrs );
838-             return  -1 ;
824+   if  (getifaddrs (& addrs ) ==  0 ) {
825+     for  (iap  =  addrs ; iap  !=  NULL ; iap  =  iap -> ifa_next ) {
826+       if  (iap -> ifa_addr  &&  (iap -> ifa_flags  &  IFF_UP ) &&  iap -> ifa_addr -> sa_family  ==  su -> su_family ) {
827+         sa  =  (struct  sockaddr_in  * )(iap -> ifa_addr );
828+         if (sa -> sin_addr .s_addr  ==  su -> su_sin .sin_addr .s_addr ) {
829+           memset (& ifr , 0 , sizeof (struct  ifreq ));
830+           strncpy (ifr .ifr_name , (char  const  * ) iap -> ifa_name , IFNAMSIZ );
831+ 
832+           /* Assign socket to an already active access point (interface) */ 
833+           ioctl (s , SIOCSIFNAME , & ifr );
834+           if  (setsockopt (s , SOL_SOCKET , SO_BINDTODEVICE , (void  * )& ifr , sizeof (ifr )) <  0 ) {
835+               SU_DEBUG_3 (("socket: %d setsockopt(SO_BINDTODEVICE) error binding to ifc %s: %s\n" ,
836+                   s , ifr .ifr_name , su_strerror (su_errno ())));
837+               freeifaddrs (addrs );
838+               return  * return_culprit  =  "setsockopt" , -1 ;
839+           }
840+           SU_DEBUG_9 (("socket: %d, bound %s to ifc: %s\n" , s ,
841+               su_inet_ntop (su -> su_family , SU_ADDR (su ), ipaddr , sizeof (ipaddr )),
842+               ifr .ifr_name ));
843+           freeifaddrs (addrs );
844+           return  0 ;
839845        }
840-         SU_DEBUG_9 (("socket: %d, bound %s to ifc: %s\n" , s ,
841-             su_inet_ntop (su -> su_family , SU_ADDR (su ), ipaddr , sizeof (ipaddr )),
842-             ifr .ifr_name ));
843-         freeifaddrs (addrs );
844-         return  0 ;
845846      }
846847    }
847-   }
848-   freeifaddrs (addrs );
848+     freeifaddrs (addrs );
849849
850-   SU_DEBUG_3 (("socket: %d: did not find ifc to bind %s\n" ,
851- 	    s , su_inet_ntop (su -> su_family , SU_ADDR (su ), ipaddr , sizeof (ipaddr ))));
852-   /* Technically it's not a "failure" */ 
850+     SU_DEBUG_3 (("socket: %d: did not find ifc to bind %s\n" ,
851+         s , su_inet_ntop (su -> su_family , SU_ADDR (su ), ipaddr , sizeof (ipaddr ))));
852+     /* Technically it's not a "failure" */ 
853+   }
853854  return  0 ;
854855}
855856#endif 
@@ -1276,6 +1277,9 @@ int tport_get_params(tport_t const *self,
12761277	       TPTAG_IDLE (tpp -> tpp_idle ),
12771278	       TPTAG_TIMEOUT (tpp -> tpp_timeout ),
12781279	       TPTAG_SOCKET_KEEPALIVE (tpp -> tpp_socket_keepalive ),
1280+ #if  defined (__linux__ )
1281+          TPTAG_SOCKET_BIND_IFC (tpp -> tpp_socket_bind_ifc ),
1282+ #endif 
12791283	       TPTAG_KEEPALIVE (tpp -> tpp_keepalive ),
12801284	       TPTAG_PINGPONG (tpp -> tpp_pingpong ),
12811285	       TPTAG_PONG2PING (tpp -> tpp_pong2ping ),
@@ -1321,6 +1325,9 @@ int tport_set_params(tport_t *self,
13211325
13221326  usize_t  mtu ;
13231327  int  connect , sdwn_error , reusable , stun_server , pong2ping ;
1328+   #if  defined (__linux__ )
1329+   int  socket_ifc ;
1330+   #endif 
13241331
13251332  if  (self  ==  NULL )
13261333    return  su_seterrno (EINVAL );
@@ -1333,6 +1340,7 @@ int tport_set_params(tport_t *self,
13331340  reusable  =  self -> tp_reusable ;
13341341  stun_server  =  tpp -> tpp_stun_server ;
13351342  pong2ping  =  tpp -> tpp_pong2ping ;
1343+   socket_ifc  =  tpp -> tpp_socket_bind_ifc ;
13361344
13371345  ta_start (ta , tag , value );
13381346
@@ -1342,6 +1350,9 @@ int tport_set_params(tport_t *self,
13421350	      TPTAG_IDLE_REF (tpp -> tpp_idle ),
13431351	      TPTAG_TIMEOUT_REF (tpp -> tpp_timeout ),
13441352	      TPTAG_SOCKET_KEEPALIVE_REF (tpp -> tpp_socket_keepalive ),
1353+ #if  defined (__linux__ )
1354+         TPTAG_SOCKET_BIND_IFC_REF (socket_ifc ),
1355+ #endif 
13451356	      TPTAG_KEEPALIVE_REF (tpp -> tpp_keepalive ),
13461357	      TPTAG_PINGPONG_REF (tpp -> tpp_pingpong ),
13471358	      TPTAG_PONG2PING_REF (pong2ping ),
0 commit comments