[pulseaudio-discuss] [PATCH v6 01/37] Support IPv6 address in pa_socket_client_new_string()

Hajime Fujita crisp.fujita at gmail.com
Sun Jan 31 20:15:58 PST 2016


From: Hajime Fujita <crisp.fujita at nifty.com>

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



More information about the pulseaudio-discuss mailing list