From 6c5c78ca85553bf972d6522a8133718ab9692eaf Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 8 Mar 2018 13:30:58 +0000 Subject: [PATCH] _dbus_append_address_from_socket: Factor out inet_sockaddr_to_string Signed-off-by: Simon McVittie https://bugs.freedesktop.org/show_bug.cgi?id=61922 --- dbus/dbus-sysdeps-unix.c | 35 ++++++++--------- dbus/dbus-sysdeps.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++ dbus/dbus-sysdeps.h | 8 ++++ 3 files changed, 121 insertions(+), 19 deletions(-) diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index d4f448a7..d7f16fc7 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -4662,6 +4662,8 @@ _dbus_append_address_from_socket (DBusSocket fd, char hostip[INET6_ADDRSTRLEN]; socklen_t size = sizeof (socket); DBusString path_str; + const char *family_name = NULL; + dbus_uint16_t port; if (getsockname (fd.fd, &socket.sa, &size)) goto err; @@ -4701,10 +4703,17 @@ _dbus_append_address_from_socket (DBusSocket fd, break; case AF_INET: - if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip))) +#ifdef AF_INET6 + case AF_INET6: +#endif + _dbus_string_init_const (&path_str, hostip); + + if (_dbus_inet_sockaddr_to_string (&socket, size, hostip, sizeof (hostip), + &family_name, &port, error)) { - if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u", - hostip, ntohs (socket.ipv4.sin_port))) + if (_dbus_string_append_printf (address, "tcp:family=%s,port=%u,host=", + family_name, port) && + _dbus_address_append_escaped (address, &path_str)) { return TRUE; } @@ -4714,25 +4723,13 @@ _dbus_append_address_from_socket (DBusSocket fd, return FALSE; } } - goto err; - -#ifdef AF_INET6 - case AF_INET6: - _dbus_string_init_const (&path_str, hostip); - if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip))) + else { - if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=", - ntohs (socket.ipv6.sin6_port)) && - _dbus_address_append_escaped (address, &path_str)) - else - { - _DBUS_SET_OOM (error); - return FALSE; - } + return FALSE; } - goto err; + /* not reached */ + break; -#endif default: dbus_set_error (error, _dbus_error_from_errno (EINVAL), diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c index 20bb8944..f15e556f 100644 --- a/dbus/dbus-sysdeps.c +++ b/dbus/dbus-sysdeps.c @@ -58,6 +58,14 @@ extern char **environ; #endif +#ifdef DBUS_WIN +#include "dbus-sockets-win.h" +#else +#include +#include +#include +#endif + /** * @defgroup DBusSysdeps Internal system-dependent API * @ingroup DBusInternals @@ -773,6 +781,95 @@ _dbus_log (DBusSystemLogSeverity severity, va_end (args); } +/* + * Try to convert the IPv4 or IPv6 address pointed to by + * sockaddr_pointer into a string. + * + * @param sockaddr_pointer A struct sockaddr_in or struct sockaddr_in6 + * @param len The length of the struct pointed to by sockaddr_pointer + * @param string An array to write the address into + * @param string_len Length of string (should usually be at least INET6_ADDRSTRLEN) + * @param family_name Used to return "ipv4" or "ipv6", or NULL to ignore + * @param port Used to return the port number, or NULL to ignore + * @returns #FALSE with errno set if the address family was not understood + */ +dbus_bool_t +_dbus_inet_sockaddr_to_string (const void *sockaddr_pointer, + size_t len, + char *string, + size_t string_len, + const char **family_name, + dbus_uint16_t *port, + DBusError *error) +{ + union + { + struct sockaddr sa; + struct sockaddr_storage storage; + struct sockaddr_in ipv4; + struct sockaddr_in6 ipv6; + } addr; + int saved_errno; + + if (len > sizeof (addr)) + return FALSE; + + _DBUS_ZERO (addr); + memcpy (&addr, sockaddr_pointer, len); + + switch (addr.sa.sa_family) + { + case AF_INET: + if (inet_ntop (AF_INET, &addr.ipv4.sin_addr, string, string_len) != NULL) + { + if (family_name != NULL) + *family_name = "ipv4"; + + if (port != NULL) + *port = ntohs (addr.ipv4.sin_port); + + return TRUE; + } + else + { + saved_errno = _dbus_get_low_level_socket_errno (); + dbus_set_error (error, _dbus_error_from_errno (saved_errno), + "Failed to get identity of IPv4 socket: %s", + _dbus_strerror (saved_errno)); + } + + return FALSE; + +#ifdef AF_INET6 + case AF_INET6: + if (inet_ntop (AF_INET6, &addr.ipv6.sin6_addr, string, string_len) != NULL) + { + if (family_name != NULL) + *family_name = "ipv6"; + + if (port != NULL) + *port = ntohs (addr.ipv6.sin6_port); + + return TRUE; + } + else + { + saved_errno = _dbus_get_low_level_socket_errno (); + dbus_set_error (error, _dbus_error_from_errno (saved_errno), + "Failed to get identity of IPv6 socket: %s", + _dbus_strerror (saved_errno)); + } + + return FALSE; +#endif + + default: + dbus_set_error (error, DBUS_ERROR_FAILED, + "Failed to get identity of socket: unknown family"); + return FALSE; + } +} + /** @} end of sysdeps */ /* tests in dbus-sysdeps-util.c */ diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index 13aeb758..4005a44f 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -694,6 +694,14 @@ void _dbus_daemon_report_reloading (void); void _dbus_daemon_report_reloaded (void); void _dbus_daemon_report_stopping (void); +dbus_bool_t _dbus_inet_sockaddr_to_string (const void *sockaddr_pointer, + size_t len, + char *string, + size_t string_len, + const char **family_name, + dbus_uint16_t *port, + DBusError *error); + /** @} */ DBUS_END_DECLS -- 2.12.3