Skip to content

Commit b56972c

Browse files
committed
Transport interface: force socket binding to network ifc
1 parent a3b8303 commit b56972c

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

libsofia-sip-ua/tport/tport.c

+50
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ typedef struct tport_nat_s tport_nat_t;
7171
#include <sofia-sip/rbtree.h>
7272

7373
#include "tport_internal.h"
74+
#include <ifaddrs.h>
75+
#if HAVE_NET_IF_H
76+
#include <net/if.h>
77+
#endif
78+
#include <sys/ioctl.h>
7479

7580
#if HAVE_FUNC
7681
#elif HAVE_FUNCTION
@@ -797,6 +802,51 @@ int tport_bind_socket(int socket,
797802
}
798803
#endif
799804

805+
if (tport_bind_socket_iface(socket, su, ai) < 0) {
806+
return -1;
807+
}
808+
809+
return 0;
810+
}
811+
812+
int tport_bind_socket_iface(int s,
813+
su_sockaddr_t *su,
814+
su_addrinfo_t *ai)
815+
{
816+
struct ifaddrs *addrs, *iap;
817+
struct sockaddr_in *sa;
818+
struct ifreq ifr;
819+
char ipaddr[SU_ADDRSIZE + 2];
820+
821+
getifaddrs(&addrs);
822+
for (iap = addrs; iap != NULL; iap = iap->ifa_next) {
823+
if (iap->ifa_addr && (iap->ifa_flags & IFF_UP) && iap->ifa_addr->sa_family == su->su_family) {
824+
sa = (struct sockaddr_in *)(iap->ifa_addr);
825+
if(sa->sin_addr.s_addr == su->su_sin.sin_addr.s_addr) {
826+
memset(&ifr, 0, sizeof(struct ifreq));
827+
strncpy(ifr.ifr_name, (char const *) iap->ifa_name, IFNAMSIZ);
828+
829+
/* Assign socket to an already active access point (interface) */
830+
ioctl(s, SIOCSIFNAME, &ifr);
831+
if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0) {
832+
SU_DEBUG_3(("socket: %d setsockopt(SO_BINDTODEVICE) error binding to ifc %s: %s\n",
833+
s, ifr.ifr_name, su_strerror(su_errno())));
834+
freeifaddrs(addrs);
835+
return -1;
836+
}
837+
SU_DEBUG_9(("socket: %d, bound %s to ifc: %s\n", s,
838+
su_inet_ntop(su->su_family, SU_ADDR(su), ipaddr, sizeof(ipaddr)),
839+
ifr.ifr_name));
840+
freeifaddrs(addrs);
841+
return 0;
842+
}
843+
}
844+
}
845+
freeifaddrs(addrs);
846+
847+
SU_DEBUG_3(("socket: %d: did not find ifc to bind %s\n",
848+
s, su_inet_ntop(su->su_family, SU_ADDR(su), ipaddr, sizeof(ipaddr))));
849+
/* Technically it's not a "failure" */
800850
return 0;
801851
}
802852

libsofia-sip-ua/tport/tport_internal.h

+3
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,9 @@ void tport_base_timer(tport_t *self, su_time_t now);
440440
int tport_bind_socket(int socket,
441441
su_addrinfo_t *ai,
442442
char const **return_culprit);
443+
int tport_bind_socket_iface(int s,
444+
su_sockaddr_t *su,
445+
su_addrinfo_t *ai);
443446
void tport_close(tport_t *self);
444447
int tport_shutdown0(tport_t *self, int how);
445448

0 commit comments

Comments
 (0)