From aeaa9091a84d8c63f59305155698aea585ec6580 Mon Sep 17 00:00:00 2001 From: Thomas Sondergaard Date: Sat, 3 Jan 2015 14:10:33 +0100 Subject: [PATCH] Bind correctly to ephemeral port on windows. Fix binding to wrong port due to network vs host byte order issue. Bring Windows version of _dbus_server_new_for_tcp_socket() more in sync with unix version. Bug: http://lists.freedesktop.org/archives/dbus/2015-January/016484.html Reviewed-by: Ralf Habacker --- dbus/dbus-sysdeps-win.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c index 2c18f40..88035a5 100644 --- a/dbus/dbus-sysdeps-win.c +++ b/dbus/dbus-sysdeps-win.c @@ -1715,10 +1715,18 @@ _dbus_listen_tcp_socket (const char *host, if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR) { DBUS_SOCKET_SET_ERRNO (); + closesocket (fd); + if (errno == WSAEADDRINUSE) + { + /* Depending on kernel policy, it may or may not + be neccessary to bind to both IPv4 & 6 addresses + so ignore EADDRINUSE here */ + tmp = tmp->ai_next; + continue; + } dbus_set_error (error, _dbus_error_from_errno (errno), "Failed to bind socket \"%s:%s\": %s", host ? host : "*", port, _dbus_strerror_from_errno ()); - closesocket (fd); goto failed; } @@ -1752,19 +1760,24 @@ _dbus_listen_tcp_socket (const char *host, to use the same port */ if (!port || !strcmp(port, "0")) { - mysockaddr_gen addr; - socklen_t addrlen = sizeof(addr); - char portbuf[10]; - - if (getsockname(fd, &addr.Address, &addrlen) == SOCKET_ERROR) + int result; + struct sockaddr_storage addr; + socklen_t addrlen; + char portbuf[50]; + + addrlen = sizeof (addr); + result = getsockname (fd, (struct sockaddr*) &addr, &addrlen); + + if (result == -1 || + (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0, + portbuf, sizeof(portbuf), + NI_NUMERICHOST)) != 0) { - DBUS_SOCKET_SET_ERRNO (); dbus_set_error (error, _dbus_error_from_errno (errno), - "Failed to resolve port \"%s:%s\": %s", - host ? host : "*", port, _dbus_strerror_from_errno()); + "Failed to resolve port \"%s:%s\": %s (%s)", + host ? host : "*", port, gai_strerror(res), res); goto failed; } - snprintf( portbuf, sizeof( portbuf ) - 1, "%d", addr.AddressIn.sin_port ); if (!_dbus_string_append(retport, portbuf)) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); -- 1.8.4.5