Hi, 2011/4/20 Luca Olivetti <l...@ventoso.org>: > the following patch adds support for NUTAG_DETECT_NETWORK_UPDATES for linux > (it's currently implemented only for OS-X). > C is not my primary language so there could be a more elegant way to do it.
Thanks Luca. I'll try to incorporate this (and your other fixes) in Sofia. --Pekka > --- > > diff --unified --recursive > sofia-sip-1.12.11.orig/libsofia-sip-ua/su/su_os_nw.c > sofia-sip-1.12.11/libsofia-sip-ua/su/su_os_nw.c > --- sofia-sip-1.12.11.orig/libsofia-sip-ua/su/su_os_nw.c 2011-03-11 > 15:49:19.000000000 +0100 > +++ sofia-sip-1.12.11/libsofia-sip-ua/su/su_os_nw.c 2011-04-20 > 19:57:20.000000000 +0200 > @@ -46,7 +46,7 @@ > #include "sofia-sip/su_os_nw.h" > #include "sofia-sip/su_debug.h" > > -#if defined(__APPLE_CC__) > +#if defined(__APPLE_CC__) || defined(__linux) > # define SU_NW_CHANGE_PTHREAD 1 > #endif > > @@ -64,6 +64,14 @@ > #include <SystemConfiguration/SCSchemaDefinitions.h> > #endif /* __APPLE_CC__ */ > > +#if defined(__linux) > +#include <string.h> > +#include <netinet/in.h> > +#include <linux/netlink.h> > +#include <linux/rtnetlink.h> > +#include <net/if.h> > +#endif /* __linux */ > + > struct su_network_changed_s { > su_root_t *su_root; > su_home_t *su_home; > @@ -80,7 +88,7 @@ > su_network_changed_magic_t *su_network_changed_magic; > }; > > -#if defined(__APPLE_CC__) > +#if defined(__APPLE_CC__) || defined(__linux) > static void su_nw_changed_msg_recv(su_root_magic_t *rm, > su_msg_r msg, > su_network_changed_t *snc) > @@ -95,8 +103,9 @@ > > return; > } > +#endif > > - > +#if defined(__APPLE_CC__) > void nw_changed_cb(SCDynamicStoreRef store, > CFArrayRef changedKeys, > void *info) > @@ -242,6 +251,86 @@ > } > #endif > > +#if defined(__linux) > +static void *su_start_nw_os_thread(void *ptr) > +{ > + su_network_changed_t *snc = (su_network_changed_t *) ptr; > + > + assert(snc); > + > + struct sockaddr_nl addr; > + int sock, len; > + char buffer[4096]; > + struct nlmsghdr *nlh; > + > + if ((sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) { > + perror("su_start_nw_os_thread: couldn't open NETLINK_ROUTE socket"); > + return NULL; > + } > + > + memset(&addr, 0, sizeof(addr)); > + addr.nl_family = AF_NETLINK; > + addr.nl_groups = RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR; > + if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) { > + perror("su_start_nw_os_thread: couldn't bind"); > + return NULL; > + } > + > + nlh = (struct nlmsghdr *)buffer; > + struct timeval tv; > + int changes; > + int forever; > + > + while(1) { > + changes = 0; > + forever = 1; > + /* first notification, wait forever */ > + tv.tv_sec = 0; > + tv.tv_usec = 0; > + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); > + while ((len = recv(sock, nlh, 4096, 0)) > 0) { > + while ((NLMSG_OK(nlh, len)) && (nlh->nlmsg_type != NLMSG_DONE)) { > + if (nlh->nlmsg_type == RTM_NEWADDR || nlh->nlmsg_type == RTM_DELADDR > ) { > + struct ifaddrmsg *ifa = (struct ifaddrmsg *) NLMSG_DATA(nlh); > + if (ifa->ifa_family == AF_INET || ifa->ifa_family == AF_INET6) > + changes =1; > + } > + nlh = NLMSG_NEXT(nlh, len); > + } > + if (changes && forever) { > + /* wait for some more notifications */ > + forever = 0; > + tv.tv_sec = 2; > + tv.tv_usec = 0; > + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); > + } > + } > + if (errno == EAGAIN || errno == EWOULDBLOCK) { > + su_network_changed_t *snc2; > + su_msg_r rmsg = SU_MSG_R_INIT; > + > + if (su_msg_create(rmsg, > + su_root_task(snc->su_root), > + su_root_task(snc->su_root), > + su_nw_changed_msg_recv, > + sizeof *snc) != SU_FAILURE) { > + snc2 = su_msg_data(rmsg); assert(snc2); > + snc2->su_root = snc->su_root; > + snc2->su_home = snc->su_home; > + snc2->su_os_thread = snc->su_os_thread; > + snc2->su_network_changed_cb = snc->su_network_changed_cb; > + snc2->su_network_changed_magic = snc->su_network_changed_magic; > + if (su_msg_send(rmsg) == SU_FAILURE) { > + su_msg_destroy(rmsg); > + } > + } > + } else > + break; > + } > + return 0; > +} > +#endif /* __linux */ > + > /** Register a callback for the network change event. > * > * @since New in @VERSION_1_12_2. > > > ------------------------------------------------------------------------------ > Benefiting from Server Virtualization: Beyond Initial Workload > Consolidation -- Increasing the use of server virtualization is a top > priority.Virtualization can reduce costs, simplify management, and improve > application availability and disaster protection. Learn more about boosting > the value of server virtualization. http://p.sf.net/sfu/vmware-sfdev2dev > _______________________________________________ > Sofia-sip-devel mailing list > Sofia-sip-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/sofia-sip-devel > -- Pekka.Pessi mail at nokia.com ------------------------------------------------------------------------------ Benefiting from Server Virtualization: Beyond Initial Workload Consolidation -- Increasing the use of server virtualization is a top priority.Virtualization can reduce costs, simplify management, and improve application availability and disaster protection. Learn more about boosting the value of server virtualization. http://p.sf.net/sfu/vmware-sfdev2dev _______________________________________________ Sofia-sip-devel mailing list Sofia-sip-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/sofia-sip-devel