Use newer IP_MULTICAST_IF API
Use newer API for IP_MULTICAST_IF which allows one to specify
interface by index, not by address. Introduced in Linux 3.5, it IMHO should
be available on all systems that declare struct ip_mreqn.
This fixes operation failure when a system has multiple interfaces
with same address, but only on of them is desired. Example:
> grep interface /usr/local/etc/minidlna.conf
network_interface=igb0
> ifconfig igb0
igb0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 0c:c4:7a:xx:xx:xx
        inet 10.1.10.3 netmask 0xffffff00 broadcast 10.1.10.255
        media: Ethernet autoselect (1000baseT <full-duplex>)
        status: active
> ifconfig ng0
ng0: flags=88d1<UP,POINTOPOINT,RUNNING,NOARP,SIMPLEX,MULTICAST> metric 0 mtu 1454
        inet 10.1.10.3 --> 10.1.10.2 netmask 0xffffffff
In such configuration, ng0 would be chosen before this fix.
			
			
This commit is contained in:
		
				
					committed by
					
						 Justin Maggard
						Justin Maggard
					
				
			
			
				
	
			
			
			
						parent
						
							256d271201
						
					
				
				
					commit
					36b9136d2b
				
			
							
								
								
									
										15
									
								
								minissdp.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								minissdp.c
									
									
									
									
									
								
							| @@ -145,7 +145,11 @@ OpenAndConfSSDPNotifySocket(struct lan_addr_s *iface) | |||||||
| 	int s; | 	int s; | ||||||
| 	unsigned char loopchar = 0; | 	unsigned char loopchar = 0; | ||||||
| 	uint8_t ttl = 4; | 	uint8_t ttl = 4; | ||||||
|  | #ifdef HAVE_STRUCT_IP_MREQN | ||||||
|  | 	struct ip_mreqn imr; | ||||||
|  | #else | ||||||
| 	struct in_addr mc_if; | 	struct in_addr mc_if; | ||||||
|  | #endif | ||||||
| 	struct sockaddr_in sockname; | 	struct sockaddr_in sockname; | ||||||
| 	 | 	 | ||||||
| 	s = socket(PF_INET, SOCK_DGRAM, 0); | 	s = socket(PF_INET, SOCK_DGRAM, 0); | ||||||
| @@ -155,8 +159,6 @@ OpenAndConfSSDPNotifySocket(struct lan_addr_s *iface) | |||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	mc_if.s_addr = iface->addr.s_addr; |  | ||||||
|  |  | ||||||
| 	if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loopchar, sizeof(loopchar)) < 0) | 	if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loopchar, sizeof(loopchar)) < 0) | ||||||
| 	{ | 	{ | ||||||
| 		DPRINTF(E_ERROR, L_SSDP, "setsockopt(udp_notify, IP_MULTICAST_LOOP): %s\n", strerror(errno)); | 		DPRINTF(E_ERROR, L_SSDP, "setsockopt(udp_notify, IP_MULTICAST_LOOP): %s\n", strerror(errno)); | ||||||
| @@ -164,7 +166,14 @@ OpenAndConfSSDPNotifySocket(struct lan_addr_s *iface) | |||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, (char *)&mc_if, sizeof(mc_if)) < 0) | #ifdef HAVE_STRUCT_IP_MREQN | ||||||
|  | 	imr.imr_address = iface->addr; | ||||||
|  | 	imr.imr_ifindex = iface->ifindex; | ||||||
|  | 	if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &imr, sizeof(imr)) < 0) | ||||||
|  | #else | ||||||
|  | 	mc_if = iface->addr; | ||||||
|  | 	if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &mc_if, sizeof(mc_if)) < 0) | ||||||
|  | #endif | ||||||
| 	{ | 	{ | ||||||
| 		DPRINTF(E_ERROR, L_SSDP, "setsockopt(udp_notify, IP_MULTICAST_IF): %s\n", strerror(errno)); | 		DPRINTF(E_ERROR, L_SSDP, "setsockopt(udp_notify, IP_MULTICAST_IF): %s\n", strerror(errno)); | ||||||
| 		close(s); | 		close(s); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user