Function to find goot reply socket for IPv4 Broadcast Requests
FossilOrigin-Name: 4f0280443244ca86f2b0575642e33da419ac1466df06c75b800e175f27124cc3
This commit is contained in:
		@ -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; i<socklist_len;i++){
 | 
				
			||||||
 | 
							/* we can only determine a reply socket for IPv4 */
 | 
				
			||||||
 | 
							if (socklist[i].addr.sa_family != AF_INET)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							/* and we want only a unicast socket for reply */
 | 
				
			||||||
 | 
							if (socklist[i].type != SOCKLIST_UNICAST_SOCKET)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							/* the first fd would be always the best if don't
 | 
				
			||||||
 | 
							 * find later a better one */
 | 
				
			||||||
 | 
							if (bestsockfd == -1){
 | 
				
			||||||
 | 
								bestsockfd = socklist[i].sockfd;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* get our source address and nemask */
 | 
				
			||||||
 | 
							uint32_t addr = ((struct sockaddr_in*)&socklist[i].addr)->sin_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)
 | 
					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);
 | 
						int rc = getaddrinfo(addr,port,&hints,&res0);
 | 
				
			||||||
	if (rc!=0) {
 | 
						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;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for(res=res0; res; res=res->ai_next){
 | 
						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;
 | 
							struct sockaddr *sa = res->ai_addr;
 | 
				
			||||||
		int sockfd = socket(res->ai_addr->sa_family, SOCK_DGRAM, 0);
 | 
							int sockfd = socket(res->ai_addr->sa_family, SOCK_DGRAM, 0);
 | 
				
			||||||
		/* create socket */
 | 
							/* 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].type=SOCKLIST_UNICAST_SOCKET;
 | 
				
			||||||
		socklist[socklist_len].ac_proto=ac_proto;
 | 
							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++;
 | 
							socklist_len++;
 | 
				
			||||||
		cw_log(LOG_INFO,"Bound to: %s (%i)",addr,sockfd);
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	freeaddrinfo(res0);	
 | 
						freeaddrinfo(res0);	
 | 
				
			||||||
 | 
				
			|||||||
@ -33,6 +33,8 @@ struct socklistelem{
 | 
				
			|||||||
	int family;
 | 
						int family;
 | 
				
			||||||
	int wtpcount;
 | 
						int wtpcount;
 | 
				
			||||||
	int ac_proto;
 | 
						int ac_proto;
 | 
				
			||||||
 | 
						struct sockaddr netmask;
 | 
				
			||||||
 | 
						struct sockaddr addr;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user