use LinkLocal address for HTTP when needed

should fix #229

should be tested...
This commit is contained in:
Thomas Bernard 2017-03-13 13:01:00 +01:00
parent da64fd85cb
commit 0cc906169a
1 changed files with 33 additions and 3 deletions

View File

@ -1,7 +1,7 @@
/* $Id: minissdp.c,v 1.77 2015/08/26 07:36:52 nanard Exp $ */ /* $Id: minissdp.c,v 1.77 2015/08/26 07:36:52 nanard Exp $ */
/* MiniUPnP project /* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2016 Thomas Bernard * (c) 2006-2017 Thomas Bernard
* This software is subject to the conditions detailed * This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */ * in the LICENCE file provided within the distribution */
@ -17,6 +17,10 @@
#include <syslog.h> #include <syslog.h>
#include "config.h" #include "config.h"
#if defined(ENABLE_IPV6) && defined(UPNP_STRICT)
#include <ifaddrs.h>
#endif /* defined(ENABLE_IPV6) && defined(UPNP_STRICT) */
#include "upnpdescstrings.h" #include "upnpdescstrings.h"
#include "miniupnpdpath.h" #include "miniupnpdpath.h"
#include "upnphttp.h" #include "upnphttp.h"
@ -116,6 +120,29 @@ AddMulticastMembershipIPv6(int s, unsigned int ifindex)
} }
#endif #endif
#if defined(ENABLE_IPV6) && defined(UPNP_STRICT)
static int get_link_local_addr(unsigned scope_id, struct in6_addr * addr6)
{
struct ifaddrs * ifap;
struct ifaddrs * ife;
if(getifaddrs(&ifap)<0) {
syslog(LOG_ERR, "getifaddrs: %m");
return -1;
}
for(ife = ifap; ife != NULL; ife = ife->ifa_next) {
if(ife->ifa_addr == NULL) continue;
if(ife->ifa_addr->sa_family != AF_INET6) continue;
if(!IN6_IS_ADDR_LINKLOCAL(&(((const struct sockaddr_in6 *)ife->ifa_addr)->sin6_addr))) continue;
if(scope_id != if_nametoindex(ife->ifa_name)) continue;
memcpy(addr6, &(((const struct sockaddr_in6 *)ife->ifa_addr)->sin6_addr), sizeof(struct in6_addr));
break;
}
freeifaddrs(ifap);
return 0;
}
#endif /* defined(ENABLE_IPV6) && defined(UPNP_STRICT) */
/* Open and configure the socket listening for /* Open and configure the socket listening for
* SSDP udp packets sent on 239.255.255.250 port 1900 * SSDP udp packets sent on 239.255.255.250 port 1900
* SSDP v6 udp packets sent on FF02::C, or FF05::C, port 1900 */ * SSDP v6 udp packets sent on FF02::C, or FF05::C, port 1900 */
@ -962,10 +989,13 @@ ProcessSSDPData(int s, const char *bufr, int n,
/* retrieve the IPv6 address which /* retrieve the IPv6 address which
* will be used locally to reach sender */ * will be used locally to reach sender */
memset(&addr6, 0, sizeof(addr6)); memset(&addr6, 0, sizeof(addr6));
if(get_src_for_route_to (sender, &addr6, &addr6_len, &index) < 0) { if(IN6_IS_ADDR_LINKLOCAL(&(((struct sockaddr_in6 *)sender)->sin6_addr))) {
get_link_local_addr(((struct sockaddr_in6 *)sender)->sin6_scope_id, &addr6);
} else if(get_src_for_route_to (sender, &addr6, &addr6_len, &index) < 0) {
syslog(LOG_WARNING, "get_src_for_route_to() failed, using %s", ipv6_addr_for_http_with_brackets); syslog(LOG_WARNING, "get_src_for_route_to() failed, using %s", ipv6_addr_for_http_with_brackets);
announced_host = ipv6_addr_for_http_with_brackets; announced_host = ipv6_addr_for_http_with_brackets;
} else { }
if(announced_host == NULL) {
if(inet_ntop(AF_INET6, &addr6, if(inet_ntop(AF_INET6, &addr6,
announced_host_buf+1, announced_host_buf+1,
sizeof(announced_host_buf) - 2)) { sizeof(announced_host_buf) - 2)) {