From: Hajime Fujita <crisp.fujita@xxxxxxxxx> pa_socket_client_new_string() did not work as expected when an IPv6 address string like "2001:db8::1" is passed as the "name" parameter. This is because the name parameter is then passed to pa_parse_address(), which thinks the last colon as a separator between hostname (or address) and a port number. To prevent pa_parse_address() from doing this, an IPv6 address must be bracketed with "[]" (e.g. "[2001:db8::1]"). [1] This patch fixes pa_socket_client_new_string() so that it internally adds brackets to an IPv6 address. This decision is based on a discussion at [2]. [1]: http://lists.freedesktop.org/archives/pulseaudio-discuss/2014-October/022010.html [2]: http://lists.freedesktop.org/archives/pulseaudio-discuss/2014-November/022401.html --- src/pulsecore/parseaddr.c | 11 +++++++++++ src/pulsecore/parseaddr.h | 2 ++ src/pulsecore/socket-client.c | 21 +++++++++++++++++++-- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/parseaddr.c b/src/pulsecore/parseaddr.c index 7f72e79..b909f52 100644 --- a/src/pulsecore/parseaddr.c +++ b/src/pulsecore/parseaddr.c @@ -143,3 +143,14 @@ bool pa_is_ip_address(const char *a) { return false; } + +bool pa_is_ip6_address(const char *a) { + char buf[INET6_ADDRSTRLEN]; + + pa_assert(a); + + if (inet_pton(AF_INET6, a, buf) >= 1) + return true; + + return false; +} diff --git a/src/pulsecore/parseaddr.h b/src/pulsecore/parseaddr.h index 5d2c358..6bb4d85 100644 --- a/src/pulsecore/parseaddr.h +++ b/src/pulsecore/parseaddr.h @@ -41,4 +41,6 @@ int pa_parse_address(const char *a, pa_parsed_address *ret_p); bool pa_is_ip_address(const char *a); +bool pa_is_ip6_address(const char *a); + #endif diff --git a/src/pulsecore/socket-client.c b/src/pulsecore/socket-client.c index b4067f0..c87406d 100644 --- a/src/pulsecore/socket-client.c +++ b/src/pulsecore/socket-client.c @@ -428,12 +428,28 @@ static void start_timeout(pa_socket_client *c, bool use_rtclock) { pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, bool use_rtclock, const char*name, uint16_t default_port) { pa_socket_client *c = NULL; pa_parsed_address a; + char *name_buf; pa_assert(m); pa_assert(name); - if (pa_parse_address(name, &a) < 0) - return NULL; + a.path_or_host = NULL; + + if (pa_is_ip6_address(name)) { + size_t len = strlen(name); + name_buf = pa_xmalloc(len + 3); + memcpy(name_buf + 1, name, len); + name_buf[0] = '['; + name_buf[len + 1] = ']'; + name_buf[len + 2] = '\0'; + } else { + name_buf = pa_xstrdup(name); + } + + if (pa_parse_address(name_buf, &a) < 0) { + pa_log_warn("parsing address failed: %s", name_buf); + goto finish; + } if (!a.port) a.port = default_port; @@ -530,6 +546,7 @@ pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, bool use_rtclo } finish: + pa_xfree(name_buf); pa_xfree(a.path_or_host); return c; -- 2.5.0