aboutsummaryrefslogtreecommitdiffstats
path: root/sockets.c
diff options
context:
space:
mode:
Diffstat (limited to 'sockets.c')
-rw-r--r--sockets.c70
1 files changed, 59 insertions, 11 deletions
diff --git a/sockets.c b/sockets.c
index be40a56..87ee567 100644
--- a/sockets.c
+++ b/sockets.c
@@ -17,6 +17,9 @@
#include <stdlib.h>
#include <string.h>
#include "android/utils/path.h"
+#include "android/utils/debug.h"
+
+#define D(...) VERBOSE_PRINT(socket,__VA_ARGS__)
#ifdef _WIN32
# define xxWIN32_LEAN_AND_MEAN
@@ -122,7 +125,7 @@ _fix_errno( void )
unix = werr->unix;
break;
}
- }
+ }
errno = unix;
return -1;
}
@@ -651,8 +654,51 @@ sock_address_init_resolve( SockAddress* a, const char* hostname, uint16_t por
return _set_errno(err);
}
- ret = sock_address_from_bsd( a, res->ai_addr, res->ai_addrlen );
- freeaddrinfo(res);
+ /* Parse the returned list of addresses. */
+ {
+ struct addrinfo* res_ipv4 = NULL;
+ struct addrinfo* res_ipv6 = NULL;
+ struct addrinfo* r;
+
+ /* If preferIn6 is false, we stop on the first IPv4 address,
+ * otherwise, we stop on the first IPv6 one
+ */
+ for (r = res; r != NULL; r = r->ai_next) {
+ if (r->ai_family == AF_INET && res_ipv4 == NULL) {
+ res_ipv4 = r;
+ if (!preferIn6)
+ break;
+ }
+ else if (r->ai_family == AF_INET6 && res_ipv6 == NULL) {
+ res_ipv6 = r;
+ if (preferIn6)
+ break;
+ }
+ }
+
+ /* Select the best address in 'r', which will be NULL
+ * if there is no corresponding address.
+ */
+ if (preferIn6) {
+ r = res_ipv6;
+ if (r == NULL)
+ r = res_ipv4;
+ } else {
+ r = res_ipv4;
+ if (r == NULL)
+ r = res_ipv6;
+ }
+
+ if (r == NULL) {
+ ret = _set_errno(ENOENT);
+ goto Exit;
+ }
+
+ /* Convert to a SockAddress */
+ ret = sock_address_from_bsd( a, r->ai_addr, r->ai_addrlen );
+ if (ret < 0)
+ goto Exit;
+ }
/* need to set the port */
switch (a->family) {
@@ -661,6 +707,8 @@ sock_address_init_resolve( SockAddress* a, const char* hostname, uint16_t por
default: ;
}
+Exit:
+ freeaddrinfo(res);
return ret;
}
@@ -1001,15 +1049,15 @@ socket_bind_server( int s, const SockAddress* to, SocketType type )
socket_set_xreuseaddr(s);
if (socket_bind(s, to) < 0) {
- dprint("could not bind server socket address %s: %s",
- sock_address_to_string(to), errno_str);
+ D("could not bind server socket address %s: %s",
+ sock_address_to_string(to), errno_str);
goto FAIL;
}
if (type == SOCKET_STREAM) {
if (socket_listen(s, 4) < 0) {
- dprint("could not listen server socket %s: %s",
- sock_address_to_string(to), errno_str);
+ D("could not listen server socket %s: %s",
+ sock_address_to_string(to), errno_str);
goto FAIL;
}
}
@@ -1025,8 +1073,8 @@ static int
socket_connect_client( int s, const SockAddress* to )
{
if (socket_connect(s, to) < 0) {
- dprint( "could not connect client socket to %s: %s\n",
- sock_address_to_string(to), errno_str );
+ D( "could not connect client socket to %s: %s\n",
+ sock_address_to_string(to), errno_str );
socket_close(s);
return -1;
}
@@ -1104,8 +1152,8 @@ socket_accept_any( int server_fd )
QSOCKET_CALL(fd, accept( server_fd, NULL, 0 ));
if (fd < 0) {
- dprint( "could not accept client connection from fd %d: %s",
- server_fd, errno_str );
+ D( "could not accept client connection from fd %d: %s",
+ server_fd, errno_str );
return -1;
}