From e5249b36a400f5e864026dd9ac39daaf2b2c2134 Mon Sep 17 00:00:00 2001 From: Ralf Habacker Date: Fri, 9 Mar 2018 00:18:27 +0100 Subject: [PATCH] Windows _dbus_connect_tcp_socket_with_nonce: Combine all connect() errors Previously, we took the errno from the most recent connect() error, and used a more generic diagnostic message. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=61922 --- dbus/dbus-sysdeps-win.c | 79 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 26 deletions(-) diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c index 7c351bd3..432faa22 100644 --- a/dbus/dbus-sysdeps-win.c +++ b/dbus/dbus-sysdeps-win.c @@ -1500,10 +1500,13 @@ _dbus_connect_tcp_socket_with_nonce (const char *host, const char *noncefile, DBusError *error) { + int saved_errno = 0; + DBusList *connect_errors = NULL; DBusSocket fd = DBUS_SOCKET_INIT; int res; struct addrinfo hints; struct addrinfo *ai, *tmp; + DBusError *connect_error; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -1541,8 +1544,9 @@ _dbus_connect_tcp_socket_with_nonce (const char *host, dbus_set_error (error, _dbus_error_from_errno (res), "Failed to lookup host/port: \"%s:%s\": %s (%d)", - host, port, _dbus_strerror(res), res); - return _dbus_socket_get_invalid (); + host, port, _dbus_strerror (res), res); + _dbus_socket_get_invalid (); + goto out; } tmp = ai; @@ -1550,21 +1554,45 @@ _dbus_connect_tcp_socket_with_nonce (const char *host, { if ((fd.sock = socket (tmp->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET) { - DBUS_SOCKET_SET_ERRNO (); + saved_errno = _dbus_get_low_level_socket_errno (); dbus_set_error (error, - _dbus_error_from_errno (errno), + _dbus_error_from_errno (saved_errno), "Failed to open socket: %s", - _dbus_strerror_from_errno ()); + _dbus_strerror (saved_errno)); freeaddrinfo(ai); - return _dbus_socket_get_invalid (); + _dbus_socket_invalidate (&fd); + goto out; } _DBUS_ASSERT_ERROR_IS_CLEAR(error); if (connect (fd.sock, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR) { - DBUS_SOCKET_SET_ERRNO (); + saved_errno = _dbus_get_low_level_socket_errno (); closesocket(fd.sock); - fd.sock = INVALID_SOCKET; + _dbus_socket_invalidate (&fd); + + connect_error = dbus_new0 (DBusError, 1); + + if (connect_error == NULL) + { + _DBUS_SET_OOM (error); + goto out; + } + + dbus_error_init (connect_error); + _dbus_set_error_with_inet_sockaddr (connect_error, + tmp->ai_addr, tmp->ai_addrlen, + "Failed to connect to socket", + saved_errno); + + if (!_dbus_list_append (&connect_errors, connect_error)) + { + dbus_error_free (connect_error); + dbus_free (connect_error); + _DBUS_SET_OOM (error); + goto out; + } + tmp = tmp->ai_next; continue; } @@ -1575,33 +1603,24 @@ _dbus_connect_tcp_socket_with_nonce (const char *host, if (!_dbus_socket_is_valid (fd)) { - dbus_set_error (error, - _dbus_error_from_errno (errno), - "Failed to connect to socket \"%s:%s\" %s", - host, port, _dbus_strerror_from_errno ()); - return _dbus_socket_get_invalid (); + _dbus_combine_tcp_errors (&connect_errors, "Failed to connect", + host, port, error); + goto out; } if (noncefile != NULL) { DBusString noncefileStr; dbus_bool_t ret; - if (!_dbus_string_init (&noncefileStr) || - !_dbus_string_append(&noncefileStr, noncefile)) - { - closesocket (fd.sock); - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); - return _dbus_socket_get_invalid (); - } - + _dbus_string_init_const (&noncefileStr, noncefile); ret = _dbus_send_nonce (fd, &noncefileStr, error); - _dbus_string_free (&noncefileStr); if (!ret) { closesocket (fd.sock); - return _dbus_socket_get_invalid (); + _dbus_socket_invalidate (&fd); + goto out; } } @@ -1611,7 +1630,15 @@ _dbus_connect_tcp_socket_with_nonce (const char *host, if (!_dbus_set_socket_nonblocking (fd, error)) { closesocket (fd.sock); - return _dbus_socket_get_invalid (); + _dbus_socket_invalidate (&fd); + goto out; + } + +out: + while ((connect_error = _dbus_list_pop_first (&connect_errors))) + { + dbus_error_free (connect_error); + dbus_free (connect_error); } return fd; @@ -1710,7 +1737,7 @@ _dbus_listen_tcp_socket (const char *host, { saved_errno = _dbus_get_low_level_socket_errno (); dbus_set_error (error, - saved_errno, + _dbus_error_from_errno (saved_errno), "Failed to open socket: %s", _dbus_strerror (saved_errno)); goto failed; @@ -1808,7 +1835,7 @@ _dbus_listen_tcp_socket (const char *host, NI_NUMERICSERV)) != 0) { saved_errno = _dbus_get_low_level_socket_errno (); - dbus_set_error (error, saved_errno, + dbus_set_error (error, _dbus_error_from_errno (saved_errno), "Failed to resolve port \"%s:%s\": %s", host ? host : "*", port, _dbus_strerror (saved_errno)); goto failed; -- 2.12.3