@@ -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 = 1 ;
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