mirror of
https://github.com/status-im/miniupnp.git
synced 2025-02-17 00:17:40 +00:00
miniupnpd: disable IPV6 if socket(PF_INET6) returns EAFNOSUPPORT
This commit is contained in:
parent
9f78015a5b
commit
72463253dc
@ -113,9 +113,9 @@ volatile sig_atomic_t should_send_public_address_change_notif = 0;
|
||||
* setup the socket used to handle incoming HTTP connections. */
|
||||
static int
|
||||
#ifdef ENABLE_IPV6
|
||||
OpenAndConfHTTPSocket(unsigned short port, int ipv6)
|
||||
OpenAndConfHTTPSocket(unsigned short * port, int ipv6)
|
||||
#else
|
||||
OpenAndConfHTTPSocket(unsigned short port)
|
||||
OpenAndConfHTTPSocket(unsigned short * port)
|
||||
#endif
|
||||
{
|
||||
int s;
|
||||
@ -128,13 +128,24 @@ OpenAndConfHTTPSocket(unsigned short port)
|
||||
#endif
|
||||
socklen_t listenname_len;
|
||||
|
||||
if( (s = socket(
|
||||
s = socket(
|
||||
#ifdef ENABLE_IPV6
|
||||
ipv6 ? PF_INET6 : PF_INET,
|
||||
ipv6 ? PF_INET6 : PF_INET,
|
||||
#else
|
||||
PF_INET,
|
||||
PF_INET,
|
||||
#endif
|
||||
SOCK_STREAM, 0)) < 0)
|
||||
SOCK_STREAM, 0);
|
||||
#ifdef ENABLE_IPV6
|
||||
if(s < 0 && ipv6 && errno == EAFNOSUPPORT)
|
||||
{
|
||||
/* the system doesn't support IPV6 */
|
||||
syslog(LOG_WARNING, "socket(PF_INET6, ...) failed with EAFNOSUPPORT, disabling IPv6");
|
||||
SETFLAG(IPV6DISABLEDMASK);
|
||||
ipv6 = 0;
|
||||
s = socket(PF_INET, SOCK_STREAM, 0);
|
||||
}
|
||||
#endif
|
||||
if(s < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "socket(http): %m");
|
||||
return -1;
|
||||
@ -163,20 +174,20 @@ OpenAndConfHTTPSocket(unsigned short port)
|
||||
{
|
||||
memset(&listenname6, 0, sizeof(struct sockaddr_in6));
|
||||
listenname6.sin6_family = AF_INET6;
|
||||
listenname6.sin6_port = htons(port);
|
||||
listenname6.sin6_port = htons(*port);
|
||||
listenname6.sin6_addr = ipv6_bind_addr;
|
||||
listenname_len = sizeof(struct sockaddr_in6);
|
||||
} else {
|
||||
memset(&listenname4, 0, sizeof(struct sockaddr_in));
|
||||
listenname4.sin_family = AF_INET;
|
||||
listenname4.sin_port = htons(port);
|
||||
listenname4.sin_port = htons(*port);
|
||||
listenname4.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
listenname_len = sizeof(struct sockaddr_in);
|
||||
}
|
||||
#else
|
||||
memset(&listenname, 0, sizeof(struct sockaddr_in));
|
||||
listenname.sin_family = AF_INET;
|
||||
listenname.sin_port = htons(port);
|
||||
listenname.sin_port = htons(*port);
|
||||
listenname.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
listenname_len = sizeof(struct sockaddr_in);
|
||||
#endif
|
||||
@ -201,6 +212,29 @@ OpenAndConfHTTPSocket(unsigned short port)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(*port == 0) {
|
||||
#ifdef ENABLE_IPV6
|
||||
if(ipv6) {
|
||||
struct sockaddr_in6 sockinfo;
|
||||
socklen_t len = sizeof(struct sockaddr_in6);
|
||||
if (getsockname(s, (struct sockaddr *)&sockinfo, &len) < 0) {
|
||||
syslog(LOG_ERR, "getsockname(): %m");
|
||||
} else {
|
||||
*port = ntohs(sockinfo.sin6_port);
|
||||
}
|
||||
} else {
|
||||
#endif /* ENABLE_IPV6 */
|
||||
struct sockaddr_in sockinfo;
|
||||
socklen_t len = sizeof(struct sockaddr_in);
|
||||
if (getsockname(s, (struct sockaddr *)&sockinfo, &len) < 0) {
|
||||
syslog(LOG_ERR, "getsockname(): %m");
|
||||
} else {
|
||||
*port = ntohs(sockinfo.sin_port);
|
||||
}
|
||||
#ifdef ENABLE_IPV6
|
||||
}
|
||||
#endif /* ENABLE_IPV6 */
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -1592,79 +1626,49 @@ main(int argc, char * * argv)
|
||||
|
||||
if(GETFLAG(ENABLEUPNPMASK))
|
||||
{
|
||||
unsigned short listen_port;
|
||||
listen_port = (v.port > 0) ? v.port : 0;
|
||||
/* open socket for HTTP connections. Listen on the 1st LAN address */
|
||||
#ifdef ENABLE_IPV6
|
||||
shttpl = OpenAndConfHTTPSocket((v.port > 0) ? v.port : 0, 1);
|
||||
shttpl = OpenAndConfHTTPSocket(&listen_port, 1);
|
||||
#else /* ENABLE_IPV6 */
|
||||
shttpl = OpenAndConfHTTPSocket((v.port > 0) ? v.port : 0);
|
||||
shttpl = OpenAndConfHTTPSocket(&listen_port);
|
||||
#endif /* ENABLE_IPV6 */
|
||||
if(shttpl < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "Failed to open socket for HTTP. EXITING");
|
||||
return 1;
|
||||
}
|
||||
if(v.port <= 0) {
|
||||
#ifdef ENABLE_IPV6
|
||||
struct sockaddr_in6 sockinfo;
|
||||
socklen_t len = sizeof(struct sockaddr_in6);
|
||||
if (getsockname(shttpl, (struct sockaddr *)&sockinfo, &len) < 0) {
|
||||
syslog(LOG_ERR, "getsockname(): %m");
|
||||
return 1;
|
||||
}
|
||||
v.port = ntohs(sockinfo.sin6_port);
|
||||
#else /* ENABLE_IPV6 */
|
||||
struct sockaddr_in sockinfo;
|
||||
socklen_t len = sizeof(struct sockaddr_in);
|
||||
if (getsockname(shttpl, (struct sockaddr *)&sockinfo, &len) < 0) {
|
||||
syslog(LOG_ERR, "getsockname(): %m");
|
||||
return 1;
|
||||
}
|
||||
v.port = ntohs(sockinfo.sin_port);
|
||||
#endif /* ENABLE_IPV6 */
|
||||
}
|
||||
v.port = listen_port;
|
||||
syslog(LOG_NOTICE, "HTTP listening on port %d", v.port);
|
||||
#if defined(V6SOCKETS_ARE_V6ONLY) && defined(ENABLE_IPV6)
|
||||
shttpl_v4 = OpenAndConfHTTPSocket(v.port, 0);
|
||||
if(shttpl_v4 < 0)
|
||||
if(!GETFLAG(IPV6DISABLEDMASK))
|
||||
{
|
||||
syslog(LOG_ERR, "Failed to open socket for HTTP on port %hu (IPv4). EXITING", v.port);
|
||||
return 1;
|
||||
shttpl_v4 = OpenAndConfHTTPSocket(&listen_port, 0);
|
||||
if(shttpl_v4 < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "Failed to open socket for HTTP on port %hu (IPv4). EXITING", v.port);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif /* V6SOCKETS_ARE_V6ONLY */
|
||||
#ifdef ENABLE_HTTPS
|
||||
/* https */
|
||||
listen_port = (v.https_port > 0) ? v.https_port : 0;
|
||||
#ifdef ENABLE_IPV6
|
||||
shttpsl = OpenAndConfHTTPSocket((v.https_port > 0) ? v.https_port : 0, 1);
|
||||
shttpsl = OpenAndConfHTTPSocket(&listen_port, 1);
|
||||
#else /* ENABLE_IPV6 */
|
||||
shttpsl = OpenAndConfHTTPSocket((v.https_port > 0) ? v.https_port : 0);
|
||||
shttpsl = OpenAndConfHTTPSocket(&listen_port);
|
||||
#endif /* ENABLE_IPV6 */
|
||||
if(shttpl < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "Failed to open socket for HTTPS. EXITING");
|
||||
return 1;
|
||||
}
|
||||
if(v.https_port <= 0) {
|
||||
#ifdef ENABLE_IPV6
|
||||
struct sockaddr_in6 sockinfo;
|
||||
socklen_t len = sizeof(struct sockaddr_in6);
|
||||
if (getsockname(shttpsl, (struct sockaddr *)&sockinfo, &len) < 0) {
|
||||
syslog(LOG_ERR, "getsockname(): %m");
|
||||
return 1;
|
||||
}
|
||||
v.https_port = ntohs(sockinfo.sin6_port);
|
||||
#else /* ENABLE_IPV6 */
|
||||
struct sockaddr_in sockinfo;
|
||||
socklen_t len = sizeof(struct sockaddr_in);
|
||||
if (getsockname(shttpsl, (struct sockaddr *)&sockinfo, &len) < 0) {
|
||||
syslog(LOG_ERR, "getsockname(): %m");
|
||||
return 1;
|
||||
}
|
||||
v.https_port = ntohs(sockinfo.sin_port);
|
||||
#endif /* ENABLE_IPV6 */
|
||||
}
|
||||
v.https_port = listen_port;
|
||||
syslog(LOG_NOTICE, "HTTPS listening on port %d", v.https_port);
|
||||
#if defined(V6SOCKETS_ARE_V6ONLY) && defined(ENABLE_IPV6)
|
||||
shttpsl_v4 = OpenAndConfHTTPSocket(v.https_port, 0);
|
||||
shttpsl_v4 = OpenAndConfHTTPSocket(&listen_port, 0);
|
||||
if(shttpsl_v4 < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "Failed to open socket for HTTPS on port %hu (IPv4). EXITING", v.https_port);
|
||||
|
Loading…
x
Reference in New Issue
Block a user