mirror of
https://gitlab.xiph.org/xiph/icecast-common.git
synced 2024-09-22 04:15:55 -04:00
Feature: Added a way to prefer IPv6 for binding sockets
This commit is contained in:
parent
87ac18cd2c
commit
265f4eb61e
51
net/sock.c
51
net/sock.c
@ -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 sockaddr_storage sa;
|
||||||
struct addrinfo hints, *res, *ai;
|
struct addrinfo hints, *res, *ai;
|
||||||
@ -722,6 +722,10 @@ sock_t sock_get_server_socket (int port, const char *sinterface)
|
|||||||
if (port < 0)
|
if (port < 0)
|
||||||
return SOCK_ERROR;
|
return SOCK_ERROR;
|
||||||
|
|
||||||
|
#ifndef AF_INET6
|
||||||
|
prefer_inet6 = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
memset(&sa, 0, sizeof(sa));
|
memset(&sa, 0, sizeof(sa));
|
||||||
memset(&hints, 0, sizeof(hints));
|
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))
|
if (getaddrinfo(sinterface, service, &hints, &res))
|
||||||
return SOCK_ERROR;
|
return SOCK_ERROR;
|
||||||
|
|
||||||
for (ai = res; ai; ai = ai->ai_next) {
|
while (true) {
|
||||||
int on = 1;
|
for (ai = res; ai; ai = ai->ai_next) {
|
||||||
|
int on = 1;
|
||||||
|
|
||||||
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
#ifdef AF_INET6
|
||||||
if (sock < 0)
|
if (prefer_inet6 && ai->ai_family != AF_INET6)
|
||||||
continue;
|
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
|
#endif
|
||||||
|
|
||||||
if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0){
|
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||||
sock_close(sock);
|
if (sock < 0)
|
||||||
continue;
|
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);
|
if (!prefer_inet6)
|
||||||
return sock;
|
break;
|
||||||
|
prefer_inet6 = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
freeaddrinfo(res);
|
freeaddrinfo(res);
|
||||||
@ -971,7 +986,7 @@ bool sock_is_ipv4_mapped_supported(void)
|
|||||||
sock_t csock;
|
sock_t csock;
|
||||||
char ip[MAX_ADDR_LEN+1];
|
char ip[MAX_ADDR_LEN+1];
|
||||||
|
|
||||||
ssock = sock_get_server_socket(0, "::");
|
ssock = sock_get_server_socket(0, "::", true);
|
||||||
|
|
||||||
if (ssock == SOCK_ERROR)
|
if (ssock == SOCK_ERROR)
|
||||||
return false;
|
return false;
|
||||||
|
@ -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);
|
int sock_read_line(sock_t sock, char *string, const int len);
|
||||||
|
|
||||||
/* server socket functions */
|
/* 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);
|
int sock_listen(sock_t serversock, int backlog);
|
||||||
sock_t sock_accept(sock_t serversock, char *ip, size_t len);
|
sock_t sock_accept(sock_t serversock, char *ip, size_t len);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user