aboutsummaryrefslogtreecommitdiffstats
path: root/sockets.c
diff options
context:
space:
mode:
authorDavid 'Digit' Turner <digit@google.com>2009-05-14 11:25:52 +0200
committerDavid 'Digit' Turner <digit@google.com>2009-05-14 11:25:52 +0200
commit3e7a92854dbf66902da5522ca3dfb2011c0ce8be (patch)
tree9d789cdf76045d2f72a03527e4f24f3cf30f069c /sockets.c
parent3d2300cb2f8f575d9e0c553c88790b5d79dda1b6 (diff)
downloadexternal_qemu-3e7a92854dbf66902da5522ca3dfb2011c0ce8be.zip
external_qemu-3e7a92854dbf66902da5522ca3dfb2011c0ce8be.tar.gz
external_qemu-3e7a92854dbf66902da5522ca3dfb2011c0ce8be.tar.bz2
This fixes sock_address_init_resolv() to properly parse the linked-list returned by getaddrinfo().
The previous implementation simply took the first entry, which could be an IPv6 address instead of an IPv4 one in certain OS setups. This created problems when "localhost" resolved to :::1 instead of 127.0.0.1. For example, when implementing inter-emulator telephony or SMS, since the caller would try to connect to localhost:5556, which was resolved to :::1:5556 while the received is listening on 127.0.0.1:5556 Also disable debugging traces that should not be activated. And make the error messages in sockets.c only dumped to the terminal when -debug-socket is active.
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;
}