1
0
Fork 0

Feature: Added a way to prefer IPv6 for binding sockets

This commit is contained in:
Philipp Schafft 2022-03-07 09:49:12 +00:00
parent 87ac18cd2c
commit 265f4eb61e
2 changed files with 34 additions and 19 deletions

View File

@ -712,7 +712,7 @@ sock_t sock_connect_wto_bind (const char *hostname, int port, const char *bnd, i
}
sock_t sock_get_server_socket (int port, const char *sinterface)
sock_t sock_get_server_socket (int port, const char *sinterface, bool prefer_inet6)
{
struct sockaddr_storage sa;
struct addrinfo hints, *res, *ai;
@ -722,6 +722,10 @@ sock_t sock_get_server_socket (int port, const char *sinterface)
if (port < 0)
return SOCK_ERROR;
#ifndef AF_INET6
prefer_inet6 = false;
#endif
memset(&sa, 0, sizeof(sa));
memset(&hints, 0, sizeof(hints));
@ -733,27 +737,38 @@ sock_t sock_get_server_socket (int port, const char *sinterface)
if (getaddrinfo(sinterface, service, &hints, &res))
return SOCK_ERROR;
for (ai = res; ai; ai = ai->ai_next) {
int on = 1;
while (true) {
for (ai = res; ai; ai = ai->ai_next) {
int on = 1;
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sock < 0)
continue;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on));
#ifdef IPV6_V6ONLY
on = 0;
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
#ifdef AF_INET6
if (prefer_inet6 && ai->ai_family != AF_INET6)
continue;
#endif
if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0){
sock_close(sock);
continue;
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sock < 0)
continue;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on));
#ifdef IPV6_V6ONLY
on = 0;
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
#endif
if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0){
sock_close(sock);
continue;
}
freeaddrinfo(res);
return sock;
}
freeaddrinfo(res);
return sock;
if (!prefer_inet6)
break;
prefer_inet6 = false;
}
freeaddrinfo(res);
@ -971,7 +986,7 @@ bool sock_is_ipv4_mapped_supported(void)
sock_t csock;
char ip[MAX_ADDR_LEN+1];
ssock = sock_get_server_socket(0, "::");
ssock = sock_get_server_socket(0, "::", true);
if (ssock == SOCK_ERROR)
return false;

View File

@ -153,7 +153,7 @@ int sock_read_bytes(sock_t sock, char *buff, size_t len);
int sock_read_line(sock_t sock, char *string, const int len);
/* server socket functions */
sock_t sock_get_server_socket(int port, const char *sinterface);
sock_t sock_get_server_socket(int port, const char *sinterface, bool prefer_inet6);
int sock_listen(sock_t serversock, int backlog);
sock_t sock_accept(sock_t serversock, char *ip, size_t len);