From 3e35b560607e3bd03bc40c4a98789d0f135e7ed3 Mon Sep 17 00:00:00 2001 From: "7u83@mail.ru" <7u83@mail.ru@noemail.net> Date: Mon, 15 Feb 2016 18:16:02 +0000 Subject: [PATCH] Function to find goot reply socket for IPv4 Broadcast Requests FossilOrigin-Name: 4f0280443244ca86f2b0575642e33da419ac1466df06c75b800e175f27124cc3 --- src/ac/socklist.c | 68 +++++++++++++++++++++++++++++++++++++++++++++-- src/ac/socklist.h | 2 ++ 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/src/ac/socklist.c b/src/ac/socklist.c index 75583841..ea9fb393 100644 --- a/src/ac/socklist.c +++ b/src/ac/socklist.c @@ -79,6 +79,50 @@ void socklist_destroy() } +/** + * Find a good reply socket (only for IPv4) + * @param sa source address + * @return socket or -1 if no socket was found + */ +int socklist_find_reply_socket(struct sockaddr *sa) +{ + int bestsockfd=-1; + int i; + + + for (i=0; isin_addr.s_addr; + uint32_t mask = ((struct sockaddr_in*)&socklist[i].netmask)->sin_addr.s_addr; + + /* get source of requested addres */ + uint32_t saddr = ((struct sockaddr_in*)sa)->sin_addr.s_addr; + + + if ( (addr & mask)== (saddr & mask) ){ + bestsockfd = socklist[i].sockfd; + } + + + } + + return bestsockfd; +} static int find_reply_socket(struct sockaddr *sa,int bc) { @@ -254,11 +298,22 @@ int socklist_add_unicast(const char *addr, const char * port, int ac_proto) int rc = getaddrinfo(addr,port,&hints,&res0); if (rc!=0) { - cw_log(LOG_ERR,"Can't bind multicast address '%s': %s",addr,gai_strerror(rc)); + cw_log(LOG_ERR,"Can't bind unicast address '%s': %s",addr,gai_strerror(rc)); return 0; } for(res=res0; res; res=res->ai_next){ + char ifname[64]; + struct sockaddr netmask; + struct sockaddr broadcast; + + ifname[0]=0; + rc = sock_getifinfo(res->ai_addr,ifname,&broadcast,&netmask); + if (!rc) { + cw_log(LOG_ERR,"No inerface found for %s, can't bind.",addr); + continue; + } + struct sockaddr *sa = res->ai_addr; int sockfd = socket(res->ai_addr->sa_family, SOCK_DGRAM, 0); /* create socket */ @@ -281,8 +336,17 @@ int socklist_add_unicast(const char *addr, const char * port, int ac_proto) socklist[socklist_len].type=SOCKLIST_UNICAST_SOCKET; socklist[socklist_len].ac_proto=ac_proto; + + if (res->ai_addr->sa_family == AF_INET ) { + memcpy(&socklist[socklist_len].netmask,&netmask,sock_addrlen(&netmask)); + memcpy(&socklist[socklist_len].addr,res->ai_addr,sock_addrlen(res->ai_addr)); + cw_log(LOG_INFO,"Bound to: %s (%i) on interface %s, netmask %s",addr,sockfd,ifname,sock_addr2str(&netmask)); + } + else{ + cw_log(LOG_INFO,"Bound to: %s (%i) on interface %s",addr,sockfd,ifname); + } socklist_len++; - cw_log(LOG_INFO,"Bound to: %s (%i)",addr,sockfd); + } freeaddrinfo(res0); diff --git a/src/ac/socklist.h b/src/ac/socklist.h index 942dc8c1..da857587 100644 --- a/src/ac/socklist.h +++ b/src/ac/socklist.h @@ -33,6 +33,8 @@ struct socklistelem{ int family; int wtpcount; int ac_proto; + struct sockaddr netmask; + struct sockaddr addr; };