Commit e894c945 authored by Simon McVittie's avatar Simon McVittie

sysdeps-unix: Set more specific IP-related errors when listening

When we have resolved a hostname/port pair to a list of IPv4 or IPv6
addresses, if we are unable to listen on a a specific one of those
addresses, we should report which one.

When IPv6 is disabled for the loopback interface, this changes the
diagnostic from:

Failed to bind socket "localhost:1234": Cannot assign requested address

to the more informative

Failed to bind socket "::1" port 1234: Cannot assign requested address
Signed-off-by: Simon McVittie's avatarSimon McVittie <smcv@collabora.com>
Reviewed-by: Ralf Habacker's avatarRalf Habacker <ralf.habacker@freenet.de>
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=61922
parent abb4d1a8
......@@ -1562,9 +1562,10 @@ _dbus_listen_tcp_socket (const char *host,
tmp = tmp->ai_next;
continue;
}
dbus_set_error (error, _dbus_error_from_errno (saved_errno),
"Failed to bind socket \"%s:%s\": %s",
host ? host : "*", port, _dbus_strerror (saved_errno));
_dbus_set_error_with_inet_sockaddr (error, tmp->ai_addr, tmp->ai_addrlen,
"Failed to bind socket",
saved_errno);
goto failed;
}
......@@ -1572,9 +1573,9 @@ _dbus_listen_tcp_socket (const char *host,
{
saved_errno = errno;
_dbus_close (fd, NULL);
dbus_set_error (error, _dbus_error_from_errno (saved_errno),
"Failed to listen on socket \"%s:%s\": %s",
host ? host : "*", port, _dbus_strerror (saved_errno));
_dbus_set_error_with_inet_sockaddr (error, tmp->ai_addr, tmp->ai_addrlen,
"Failed to listen on socket",
saved_errno);
goto failed;
}
......
......@@ -870,6 +870,44 @@ _dbus_inet_sockaddr_to_string (const void *sockaddr_pointer,
}
}
/*
* Format an error appropriate for saved_errno for the IPv4 or IPv6
* address pointed to by sockaddr_pointer of length sockaddr_len.
*
* @param error The error to set
* @param sockaddr_pointer A struct sockaddr_in or struct sockaddr_in6
* @param len The length of the struct pointed to by sockaddr_pointer
* @param description A prefix like "Failed to listen on socket"
* @param saved_errno The OS-level error number to use
*/
void
_dbus_set_error_with_inet_sockaddr (DBusError *error,
const void *sockaddr_pointer,
size_t len,
const char *description,
int saved_errno)
{
char string[INET6_ADDRSTRLEN];
dbus_uint16_t port;
const struct sockaddr *addr = sockaddr_pointer;
if (_dbus_inet_sockaddr_to_string (sockaddr_pointer, len,
string, sizeof (string), NULL, &port,
NULL))
{
dbus_set_error (error, _dbus_error_from_errno (saved_errno),
"%s \"%s\" port %u: %s",
description, string, port, _dbus_strerror (saved_errno));
}
else
{
dbus_set_error (error, _dbus_error_from_errno (saved_errno),
"%s <address of unknown family %d>: %s",
description, addr->sa_family,
_dbus_strerror (saved_errno));
}
}
/** @} end of sysdeps */
/* tests in dbus-sysdeps-util.c */
......@@ -701,6 +701,11 @@ dbus_bool_t _dbus_inet_sockaddr_to_string (const void *sockaddr_pointer,
const char **family_name,
dbus_uint16_t *port,
DBusError *error);
void _dbus_set_error_with_inet_sockaddr (DBusError *error,
const void *sockaddr_pointer,
size_t len,
const char *description,
int saved_errno);
/** @} */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment