@@ -71,7 +71,7 @@ typedef struct tport_nat_s tport_nat_t;
71
71
#include <sofia-sip/rbtree.h>
72
72
73
73
#include "tport_internal.h"
74
- #if defined (__linux__ )
74
+ #if HAVE_GETIFADDRS && defined (__linux__ )
75
75
#include <ifaddrs.h>
76
76
#if HAVE_NET_IF_H
77
77
#include <net/if.h>
@@ -520,6 +520,9 @@ tport_t *tport_tcreate(tp_stack_t *stack,
520
520
tpp -> tpp_timeout = UINT_MAX ;
521
521
tpp -> tpp_sigcomp_lifetime = UINT_MAX ;
522
522
tpp -> tpp_socket_keepalive = 30 ;
523
+ #if defined (__linux__ )
524
+ tpp -> tpp_socket_bind_ifc = 0 ;
525
+ #endif
523
526
tpp -> tpp_keepalive = 0 ;
524
527
tpp -> tpp_pingpong = 0 ;
525
528
tpp -> tpp_pong2ping = 0 ;
@@ -803,53 +806,51 @@ int tport_bind_socket(int socket,
803
806
}
804
807
}
805
808
#endif
806
- #if defined(__linux__ )
807
- if (tport_bind_socket_iface (socket , su , ai ) < 0 ) {
808
- return -1 ;
809
- }
810
- #endif
809
+
811
810
return 0 ;
812
811
}
813
812
814
- #if defined(__linux__ )
813
+ #if HAVE_GETIFADDRS && defined (__linux__ )
815
814
int 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 )
818
817
{
818
+ su_sockaddr_t * su = (su_sockaddr_t * )ai -> ai_addr ;
819
819
struct ifaddrs * addrs , * iap ;
820
820
struct sockaddr_in * sa ;
821
821
struct ifreq ifr ;
822
822
char ipaddr [SU_ADDRSIZE + 2 ];
823
823
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 ;
839
845
}
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 ;
845
846
}
846
847
}
847
- }
848
- freeifaddrs (addrs );
848
+ freeifaddrs (addrs );
849
849
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
+ }
853
854
return 0 ;
854
855
}
855
856
#endif
@@ -1276,6 +1277,9 @@ int tport_get_params(tport_t const *self,
1276
1277
TPTAG_IDLE (tpp -> tpp_idle ),
1277
1278
TPTAG_TIMEOUT (tpp -> tpp_timeout ),
1278
1279
TPTAG_SOCKET_KEEPALIVE (tpp -> tpp_socket_keepalive ),
1280
+ #if defined (__linux__ )
1281
+ TPTAG_SOCKET_BIND_IFC (tpp -> tpp_socket_bind_ifc ),
1282
+ #endif
1279
1283
TPTAG_KEEPALIVE (tpp -> tpp_keepalive ),
1280
1284
TPTAG_PINGPONG (tpp -> tpp_pingpong ),
1281
1285
TPTAG_PONG2PING (tpp -> tpp_pong2ping ),
@@ -1321,6 +1325,9 @@ int tport_set_params(tport_t *self,
1321
1325
1322
1326
usize_t mtu ;
1323
1327
int connect , sdwn_error , reusable , stun_server , pong2ping ;
1328
+ #if defined (__linux__ )
1329
+ int socket_ifc ;
1330
+ #endif
1324
1331
1325
1332
if (self == NULL )
1326
1333
return su_seterrno (EINVAL );
@@ -1333,6 +1340,7 @@ int tport_set_params(tport_t *self,
1333
1340
reusable = self -> tp_reusable ;
1334
1341
stun_server = tpp -> tpp_stun_server ;
1335
1342
pong2ping = tpp -> tpp_pong2ping ;
1343
+ socket_ifc = tpp -> tpp_socket_bind_ifc ;
1336
1344
1337
1345
ta_start (ta , tag , value );
1338
1346
@@ -1342,6 +1350,9 @@ int tport_set_params(tport_t *self,
1342
1350
TPTAG_IDLE_REF (tpp -> tpp_idle ),
1343
1351
TPTAG_TIMEOUT_REF (tpp -> tpp_timeout ),
1344
1352
TPTAG_SOCKET_KEEPALIVE_REF (tpp -> tpp_socket_keepalive ),
1353
+ #if defined (__linux__ )
1354
+ TPTAG_SOCKET_BIND_IFC_REF (socket_ifc ),
1355
+ #endif
1345
1356
TPTAG_KEEPALIVE_REF (tpp -> tpp_keepalive ),
1346
1357
TPTAG_PINGPONG_REF (tpp -> tpp_pingpong ),
1347
1358
TPTAG_PONG2PING_REF (pong2ping ),
0 commit comments