]> code.delx.au - pulseaudio/blobdiff - src/pulsecore/socket-server.c
sink-input, source-output: Don't assume that proplist has been initialized in free()
[pulseaudio] / src / pulsecore / socket-server.c
index 21c5115194f9550a15f49433da329449fc94e849..ef77563d412c1ed27f5b0f9e5f50c733a7ecf018 100644 (file)
@@ -1,5 +1,3 @@
-/* $Id$ */
-
 /***
   This file is part of PulseAudio.
 
 /***
   This file is part of PulseAudio.
 
@@ -8,7 +6,7 @@
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2 of the License,
+  by the Free Software Foundation; either version 2.1 of the License,
   or (at your option) any later version.
 
   PulseAudio is distributed in the hope that it will be useful, but
   or (at your option) any later version.
 
   PulseAudio is distributed in the hope that it will be useful, but
@@ -34,9 +32,6 @@
 #include <unistd.h>
 #include <sys/stat.h>
 
 #include <unistd.h>
 #include <sys/stat.h>
 
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
 #ifdef HAVE_SYS_UN_H
 #include <sys/un.h>
 #ifndef SUN_LEN
 #ifdef HAVE_SYS_UN_H
 #include <sys/un.h>
 #ifndef SUN_LEN
     ((size_t)(((struct sockaddr_un *) 0)->sun_path) + strlen((ptr)->sun_path))
 #endif
 #endif
     ((size_t)(((struct sockaddr_un *) 0)->sun_path) + strlen((ptr)->sun_path))
 #endif
 #endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
 #ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
 #endif
 
 #ifdef HAVE_LIBWRAP
 #include <tcpd.h>
 #ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
 #endif
 
 #ifdef HAVE_LIBWRAP
 #include <tcpd.h>
-#endif
 
 
-#ifndef HAVE_INET_NTOP
-#include "inet_ntop.h"
+/* Solaris requires that the allow_severity and deny_severity variables be
+ * defined in the client program. */
+#ifdef __sun
+#include <syslog.h>
+int allow_severity = LOG_INFO;
+int deny_severity = LOG_WARNING;
 #endif
 
 #endif
 
-#ifndef HAVE_INET_PTON
-#include "inet_pton.h"
-#endif
-
-#include "winsock.h"
+#endif /* HAVE_LIBWRAP */
 
 #include <pulse/xmalloc.h>
 #include <pulse/util.h>
 
 
 #include <pulse/xmalloc.h>
 #include <pulse/util.h>
 
+#include <pulsecore/socket.h>
 #include <pulsecore/socket-util.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-error.h>
 #include <pulsecore/refcnt.h>
 #include <pulsecore/socket-util.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-error.h>
 #include <pulsecore/refcnt.h>
+#include <pulsecore/arpa-inet.h>
 
 #include "socket-server.h"
 
 
 #include "socket-server.h"
 
@@ -83,19 +76,24 @@ struct pa_socket_server {
     char *filename;
     char *tcpwrap_service;
 
     char *filename;
     char *tcpwrap_service;
 
-    void (*on_connection)(pa_socket_server*s, pa_iochannel *io, void *userdata);
+    pa_socket_server_on_connection_cb_t on_connection;
     void *userdata;
 
     pa_io_event *io_event;
     pa_mainloop_api *mainloop;
     void *userdata;
 
     pa_io_event *io_event;
     pa_mainloop_api *mainloop;
-    enum { SOCKET_SERVER_GENERIC, SOCKET_SERVER_IPV4, SOCKET_SERVER_UNIX, SOCKET_SERVER_IPV6 } type;
+    enum {
+        SOCKET_SERVER_GENERIC,
+        SOCKET_SERVER_IPV4,
+        SOCKET_SERVER_UNIX,
+        SOCKET_SERVER_IPV6
+    } type;
 };
 
 };
 
-static void callback(pa_mainloop_api *mainloop, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) {
+static void callback(pa_mainloop_api *mainloop, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {
     pa_socket_server *s = userdata;
     pa_iochannel *io;
     int nfd;
     pa_socket_server *s = userdata;
     pa_iochannel *io;
     int nfd;
-    
+
     pa_assert(s);
     pa_assert(PA_REFCNT_VALUE(s) >= 1);
     pa_assert(s->mainloop == mainloop);
     pa_assert(s);
     pa_assert(PA_REFCNT_VALUE(s) >= 1);
     pa_assert(s->mainloop == mainloop);
@@ -106,13 +104,11 @@ static void callback(pa_mainloop_api *mainloop, pa_io_event *e, int fd, PA_GCC_U
 
     pa_socket_server_ref(s);
 
 
     pa_socket_server_ref(s);
 
-    if ((nfd = accept(fd, NULL, NULL)) < 0) {
+    if ((nfd = pa_accept_cloexec(fd, NULL, NULL)) < 0) {
         pa_log("accept(): %s", pa_cstrerror(errno));
         goto finish;
     }
 
         pa_log("accept(): %s", pa_cstrerror(errno));
         goto finish;
     }
 
-    pa_fd_set_cloexec(nfd, 1);
-
     if (!s->on_connection) {
         pa_close(nfd);
         goto finish;
     if (!s->on_connection) {
         pa_close(nfd);
         goto finish;
@@ -137,9 +133,9 @@ static void callback(pa_mainloop_api *mainloop, pa_io_event *e, int fd, PA_GCC_U
 
     /* There should be a check for socket type here */
     if (s->type == SOCKET_SERVER_IPV4)
 
     /* There should be a check for socket type here */
     if (s->type == SOCKET_SERVER_IPV4)
-        pa_socket_tcp_low_delay(fd);
+        pa_make_tcp_socket_low_delay(nfd);
     else
     else
-        pa_socket_low_delay(fd);
+        pa_make_socket_low_delay(nfd);
 
     pa_assert_se(io = pa_iochannel_new(s->mainloop, nfd, nfd));
     s->on_connection(s, io, s->userdata);
 
     pa_assert_se(io = pa_iochannel_new(s->mainloop, nfd, nfd));
     s->on_connection(s, io, s->userdata);
@@ -150,19 +146,15 @@ finish:
 
 pa_socket_server* pa_socket_server_new(pa_mainloop_api *m, int fd) {
     pa_socket_server *s;
 
 pa_socket_server* pa_socket_server_new(pa_mainloop_api *m, int fd) {
     pa_socket_server *s;
-    
+
     pa_assert(m);
     pa_assert(fd >= 0);
 
     pa_assert(m);
     pa_assert(fd >= 0);
 
-    s = pa_xnew(pa_socket_server, 1);
+    s = pa_xnew0(pa_socket_server, 1);
     PA_REFCNT_INIT(s);
     s->fd = fd;
     PA_REFCNT_INIT(s);
     s->fd = fd;
-    s->filename = NULL;
-    s->on_connection = NULL;
-    s->userdata = NULL;
-    s->tcpwrap_service = NULL;
-
     s->mainloop = m;
     s->mainloop = m;
+
     pa_assert_se(s->io_event = m->io_new(m, fd, PA_IO_EVENT_INPUT, callback, s));
 
     s->type = SOCKET_SERVER_GENERIC;
     pa_assert_se(s->io_event = m->io_new(m, fd, PA_IO_EVENT_INPUT, callback, s));
 
     s->type = SOCKET_SERVER_GENERIC;
@@ -173,7 +165,7 @@ pa_socket_server* pa_socket_server_new(pa_mainloop_api *m, int fd) {
 pa_socket_server* pa_socket_server_ref(pa_socket_server *s) {
     pa_assert(s);
     pa_assert(PA_REFCNT_VALUE(s) >= 1);
 pa_socket_server* pa_socket_server_ref(pa_socket_server *s) {
     pa_assert(s);
     pa_assert(PA_REFCNT_VALUE(s) >= 1);
-        
+
     PA_REFCNT_INC(s);
     return s;
 }
     PA_REFCNT_INC(s);
     return s;
 }
@@ -188,20 +180,18 @@ pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *file
     pa_assert(m);
     pa_assert(filename);
 
     pa_assert(m);
     pa_assert(filename);
 
-    if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
+    if ((fd = pa_socket_cloexec(PF_UNIX, SOCK_STREAM, 0)) < 0) {
         pa_log("socket(): %s", pa_cstrerror(errno));
         goto fail;
     }
 
         pa_log("socket(): %s", pa_cstrerror(errno));
         goto fail;
     }
 
-    pa_fd_set_cloexec(fd, 1);
-
+    memset(&sa, 0, sizeof(sa));
     sa.sun_family = AF_UNIX;
     sa.sun_family = AF_UNIX;
-    strncpy(sa.sun_path, filename, sizeof(sa.sun_path)-1);
-    sa.sun_path[sizeof(sa.sun_path) - 1] = 0;
+    pa_strlcpy(sa.sun_path, filename, sizeof(sa.sun_path));
 
 
-    pa_socket_low_delay(fd);
+    pa_make_socket_low_delay(fd);
 
 
-    if (bind(fd, (struct sockaddr*) &sa, SUN_LEN(&sa)) < 0) {
+    if (bind(fd, (struct sockaddr*) &sa, (socklen_t) SUN_LEN(&sa)) < 0) {
         pa_log("bind(): %s", pa_cstrerror(errno));
         goto fail;
     }
         pa_log("bind(): %s", pa_cstrerror(errno));
         goto fail;
     }
@@ -239,7 +229,7 @@ pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *file
 
 #endif /* HAVE_SYS_UN_H */
 
 
 #endif /* HAVE_SYS_UN_H */
 
-pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address, uint16_t port, const char *tcpwrap_service) {
+pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address, uint16_t port, bool fallback, const char *tcpwrap_service) {
     pa_socket_server *ss;
     int fd = -1;
     struct sockaddr_in sa;
     pa_socket_server *ss;
     int fd = -1;
     struct sockaddr_in sa;
@@ -248,19 +238,17 @@ pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address
     pa_assert(m);
     pa_assert(port);
 
     pa_assert(m);
     pa_assert(port);
 
-    if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
+    if ((fd = pa_socket_cloexec(PF_INET, SOCK_STREAM, 0)) < 0) {
         pa_log("socket(PF_INET): %s", pa_cstrerror(errno));
         goto fail;
     }
 
         pa_log("socket(PF_INET): %s", pa_cstrerror(errno));
         goto fail;
     }
 
-    pa_fd_set_cloexec(fd, 1);
-
 #ifdef SO_REUSEADDR
 #ifdef SO_REUSEADDR
-    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
+    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *) &on, sizeof(on)) < 0)
         pa_log("setsockopt(): %s", pa_cstrerror(errno));
 #endif
 
         pa_log("setsockopt(): %s", pa_cstrerror(errno));
 #endif
 
-    pa_socket_tcp_low_delay(fd);
+    pa_make_tcp_socket_low_delay(fd);
 
     memset(&sa, 0, sizeof(sa));
     sa.sin_family = AF_INET;
 
     memset(&sa, 0, sizeof(sa));
     sa.sin_family = AF_INET;
@@ -268,8 +256,19 @@ pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address
     sa.sin_addr.s_addr = htonl(address);
 
     if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
     sa.sin_addr.s_addr = htonl(address);
 
     if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
+
+        if (errno == EADDRINUSE && fallback) {
+            sa.sin_port = 0;
+
+            if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) >= 0)
+                goto good;
+        }
+
         pa_log("bind(): %s", pa_cstrerror(errno));
         goto fail;
         pa_log("bind(): %s", pa_cstrerror(errno));
         goto fail;
+
+    good:
+        ;
     }
 
     if (listen(fd, 5) < 0) {
     }
 
     if (listen(fd, 5) < 0) {
@@ -291,33 +290,34 @@ fail:
     return NULL;
 }
 
     return NULL;
 }
 
-pa_socket_server* pa_socket_server_new_ipv6(pa_mainloop_api *m, const uint8_t address[16], uint16_t port, const char *tcpwrap_service) {
+#ifdef HAVE_IPV6
+pa_socket_server* pa_socket_server_new_ipv6(pa_mainloop_api *m, const uint8_t address[16], uint16_t port, bool fallback, const char *tcpwrap_service) {
     pa_socket_server *ss;
     int fd = -1;
     struct sockaddr_in6 sa;
     pa_socket_server *ss;
     int fd = -1;
     struct sockaddr_in6 sa;
-    int on = 1;
+    int on;
 
     pa_assert(m);
     pa_assert(port > 0);
 
 
     pa_assert(m);
     pa_assert(port > 0);
 
-    if ((fd = socket(PF_INET6, SOCK_STREAM, 0)) < 0) {
+    if ((fd = pa_socket_cloexec(PF_INET6, SOCK_STREAM, 0)) < 0) {
         pa_log("socket(PF_INET6): %s", pa_cstrerror(errno));
         goto fail;
     }
 
         pa_log("socket(PF_INET6): %s", pa_cstrerror(errno));
         goto fail;
     }
 
-    pa_fd_set_cloexec(fd, 1);
-
 #ifdef IPV6_V6ONLY
 #ifdef IPV6_V6ONLY
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0)
+    on = 1;
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const void *) &on, sizeof(on)) < 0)
         pa_log("setsockopt(IPPROTO_IPV6, IPV6_V6ONLY): %s", pa_cstrerror(errno));
 #endif
 
 #ifdef SO_REUSEADDR
         pa_log("setsockopt(IPPROTO_IPV6, IPV6_V6ONLY): %s", pa_cstrerror(errno));
 #endif
 
 #ifdef SO_REUSEADDR
-    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
+    on = 1;
+    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *) &on, sizeof(on)) < 0)
         pa_log("setsockopt(SOL_SOCKET, SO_REUSEADDR, 1): %s", pa_cstrerror(errno));
 #endif
 
         pa_log("setsockopt(SOL_SOCKET, SO_REUSEADDR, 1): %s", pa_cstrerror(errno));
 #endif
 
-    pa_socket_tcp_low_delay(fd);
+    pa_make_tcp_socket_low_delay(fd);
 
     memset(&sa, 0, sizeof(sa));
     sa.sin6_family = AF_INET6;
 
     memset(&sa, 0, sizeof(sa));
     sa.sin6_family = AF_INET6;
@@ -325,8 +325,19 @@ pa_socket_server* pa_socket_server_new_ipv6(pa_mainloop_api *m, const uint8_t ad
     memcpy(sa.sin6_addr.s6_addr, address, 16);
 
     if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
     memcpy(sa.sin6_addr.s6_addr, address, 16);
 
     if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
+
+        if (errno == EADDRINUSE && fallback) {
+            sa.sin6_port = 0;
+
+            if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) >= 0)
+                goto good;
+        }
+
         pa_log("bind(): %s", pa_cstrerror(errno));
         goto fail;
         pa_log("bind(): %s", pa_cstrerror(errno));
         goto fail;
+
+    good:
+        ;
     }
 
     if (listen(fd, 5) < 0) {
     }
 
     if (listen(fd, 5) < 0) {
@@ -347,36 +358,41 @@ fail:
 
     return NULL;
 }
 
     return NULL;
 }
+#endif
 
 
-pa_socket_server* pa_socket_server_new_ipv4_loopback(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) {
+pa_socket_server* pa_socket_server_new_ipv4_loopback(pa_mainloop_api *m, uint16_t port, bool fallback, const char *tcpwrap_service) {
     pa_assert(m);
     pa_assert(port > 0);
 
     pa_assert(m);
     pa_assert(port > 0);
 
-    return pa_socket_server_new_ipv4(m, INADDR_LOOPBACK, port, tcpwrap_service);
+    return pa_socket_server_new_ipv4(m, INADDR_LOOPBACK, port, fallback, tcpwrap_service);
 }
 
 }
 
-pa_socket_server* pa_socket_server_new_ipv6_loopback(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) {
+#ifdef HAVE_IPV6
+pa_socket_server* pa_socket_server_new_ipv6_loopback(pa_mainloop_api *m, uint16_t port, bool fallback, const char *tcpwrap_service) {
     pa_assert(m);
     pa_assert(port > 0);
 
     pa_assert(m);
     pa_assert(port > 0);
 
-    return pa_socket_server_new_ipv6(m, in6addr_loopback.s6_addr, port, tcpwrap_service);
+    return pa_socket_server_new_ipv6(m, in6addr_loopback.s6_addr, port, fallback, tcpwrap_service);
 }
 }
+#endif
 
 
-pa_socket_server* pa_socket_server_new_ipv4_any(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) {
+pa_socket_server* pa_socket_server_new_ipv4_any(pa_mainloop_api *m, uint16_t port, bool fallback, const char *tcpwrap_service) {
     pa_assert(m);
     pa_assert(port > 0);
 
     pa_assert(m);
     pa_assert(port > 0);
 
-    return pa_socket_server_new_ipv4(m, INADDR_ANY, port, tcpwrap_service);
+    return pa_socket_server_new_ipv4(m, INADDR_ANY, port, fallback, tcpwrap_service);
 }
 
 }
 
-pa_socket_server* pa_socket_server_new_ipv6_any(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) {
+#ifdef HAVE_IPV6
+pa_socket_server* pa_socket_server_new_ipv6_any(pa_mainloop_api *m, uint16_t port, bool fallback, const char *tcpwrap_service) {
     pa_assert(m);
     pa_assert(port > 0);
 
     pa_assert(m);
     pa_assert(port > 0);
 
-    return pa_socket_server_new_ipv6(m, in6addr_any.s6_addr, port, tcpwrap_service);
+    return pa_socket_server_new_ipv6(m, in6addr_any.s6_addr, port, fallback, tcpwrap_service);
 }
 }
+#endif
 
 
-pa_socket_server* pa_socket_server_new_ipv4_string(pa_mainloop_api *m, const char *name, uint16_t port, const char *tcpwrap_service) {
+pa_socket_server* pa_socket_server_new_ipv4_string(pa_mainloop_api *m, const char *name, uint16_t port, bool fallback, const char *tcpwrap_service) {
     struct in_addr ipv4;
 
     pa_assert(m);
     struct in_addr ipv4;
 
     pa_assert(m);
@@ -384,12 +400,13 @@ pa_socket_server* pa_socket_server_new_ipv4_string(pa_mainloop_api *m, const cha
     pa_assert(port > 0);
 
     if (inet_pton(AF_INET, name, &ipv4) > 0)
     pa_assert(port > 0);
 
     if (inet_pton(AF_INET, name, &ipv4) > 0)
-        return pa_socket_server_new_ipv4(m, ntohl(ipv4.s_addr), port, tcpwrap_service);
+        return pa_socket_server_new_ipv4(m, ntohl(ipv4.s_addr), port, fallback, tcpwrap_service);
 
     return NULL;
 }
 
 
     return NULL;
 }
 
-pa_socket_server* pa_socket_server_new_ipv6_string(pa_mainloop_api *m, const char *name, uint16_t port, const char *tcpwrap_service) {
+#ifdef HAVE_IPV6
+pa_socket_server* pa_socket_server_new_ipv6_string(pa_mainloop_api *m, const char *name, uint16_t port, bool fallback, const char *tcpwrap_service) {
     struct in6_addr ipv6;
 
     pa_assert(m);
     struct in6_addr ipv6;
 
     pa_assert(m);
@@ -397,10 +414,11 @@ pa_socket_server* pa_socket_server_new_ipv6_string(pa_mainloop_api *m, const cha
     pa_assert(port > 0);
 
     if (inet_pton(AF_INET6, name, &ipv6) > 0)
     pa_assert(port > 0);
 
     if (inet_pton(AF_INET6, name, &ipv6) > 0)
-        return pa_socket_server_new_ipv6(m, ipv6.s6_addr, port, tcpwrap_service);
+        return pa_socket_server_new_ipv6(m, ipv6.s6_addr, port, fallback, tcpwrap_service);
 
     return NULL;
 }
 
     return NULL;
 }
+#endif
 
 static void socket_server_free(pa_socket_server*s) {
     pa_assert(s);
 
 static void socket_server_free(pa_socket_server*s) {
     pa_assert(s);
@@ -422,11 +440,11 @@ void pa_socket_server_unref(pa_socket_server *s) {
     pa_assert(s);
     pa_assert(PA_REFCNT_VALUE(s) >= 1);
 
     pa_assert(s);
     pa_assert(PA_REFCNT_VALUE(s) >= 1);
 
-    if (PA_REFCNT_DEC(s))
+    if (PA_REFCNT_DEC(s) <= 0)
         socket_server_free(s);
 }
 
         socket_server_free(s);
 }
 
-void pa_socket_server_set_callback(pa_socket_server*s, void (*on_connection)(pa_socket_server*s, pa_iochannel *io, void *userdata), void *userdata) {
+void pa_socket_server_set_callback(pa_socket_server*s, pa_socket_server_on_connection_cb_t on_connection, void *userdata) {
     pa_assert(s);
     pa_assert(PA_REFCNT_VALUE(s) >= 1);
 
     pa_assert(s);
     pa_assert(PA_REFCNT_VALUE(s) >= 1);
 
@@ -441,6 +459,7 @@ char *pa_socket_server_get_address(pa_socket_server *s, char *c, size_t l) {
     pa_assert(l > 0);
 
     switch (s->type) {
     pa_assert(l > 0);
 
     switch (s->type) {
+#ifdef HAVE_IPV6
         case SOCKET_SERVER_IPV6: {
             struct sockaddr_in6 sa;
             socklen_t sa_len = sizeof(sa);
         case SOCKET_SERVER_IPV6: {
             struct sockaddr_in6 sa;
             socklen_t sa_len = sizeof(sa);
@@ -458,11 +477,13 @@ char *pa_socket_server_get_address(pa_socket_server *s, char *c, size_t l) {
                 pa_snprintf(c, l, "tcp6:%s:%u", fqdn, (unsigned) ntohs(sa.sin6_port));
 
             } else if (memcmp(&in6addr_loopback, &sa.sin6_addr, sizeof(in6addr_loopback)) == 0) {
                 pa_snprintf(c, l, "tcp6:%s:%u", fqdn, (unsigned) ntohs(sa.sin6_port));
 
             } else if (memcmp(&in6addr_loopback, &sa.sin6_addr, sizeof(in6addr_loopback)) == 0) {
-                char hn[256];
-                if (!pa_get_host_name(hn, sizeof(hn)))
+                char *id;
+
+                if (!(id = pa_machine_id()))
                     return NULL;
 
                     return NULL;
 
-                pa_snprintf(c, l, "{%s}tcp6:localhost:%u", hn, (unsigned) ntohs(sa.sin6_port));
+                pa_snprintf(c, l, "{%s}tcp6:localhost:%u", id, (unsigned) ntohs(sa.sin6_port));
+                pa_xfree(id);
             } else {
                 char ip[INET6_ADDRSTRLEN];
 
             } else {
                 char ip[INET6_ADDRSTRLEN];
 
@@ -476,6 +497,7 @@ char *pa_socket_server_get_address(pa_socket_server *s, char *c, size_t l) {
 
             return c;
         }
 
             return c;
         }
+#endif
 
         case SOCKET_SERVER_IPV4: {
             struct sockaddr_in sa;
 
         case SOCKET_SERVER_IPV4: {
             struct sockaddr_in sa;
@@ -493,11 +515,13 @@ char *pa_socket_server_get_address(pa_socket_server *s, char *c, size_t l) {
 
                 pa_snprintf(c, l, "tcp:%s:%u", fqdn, (unsigned) ntohs(sa.sin_port));
             } else if (sa.sin_addr.s_addr == INADDR_LOOPBACK) {
 
                 pa_snprintf(c, l, "tcp:%s:%u", fqdn, (unsigned) ntohs(sa.sin_port));
             } else if (sa.sin_addr.s_addr == INADDR_LOOPBACK) {
-                char hn[256];
-                if (!pa_get_host_name(hn, sizeof(hn)))
+                char *id;
+
+                if (!(id = pa_machine_id()))
                     return NULL;
 
                     return NULL;
 
-                pa_snprintf(c, l, "{%s}tcp:localhost:%u", hn, (unsigned) ntohs(sa.sin_port));
+                pa_snprintf(c, l, "{%s}tcp:localhost:%u", id, (unsigned) ntohs(sa.sin_port));
+                pa_xfree(id);
             } else {
                 char ip[INET_ADDRSTRLEN];
 
             } else {
                 char ip[INET_ADDRSTRLEN];
 
@@ -507,22 +531,22 @@ char *pa_socket_server_get_address(pa_socket_server *s, char *c, size_t l) {
                 }
 
                 pa_snprintf(c, l, "tcp:[%s]:%u", ip, (unsigned) ntohs(sa.sin_port));
                 }
 
                 pa_snprintf(c, l, "tcp:[%s]:%u", ip, (unsigned) ntohs(sa.sin_port));
-
             }
 
             return c;
         }
 
         case SOCKET_SERVER_UNIX: {
             }
 
             return c;
         }
 
         case SOCKET_SERVER_UNIX: {
-            char hn[256];
+            char *id;
 
             if (!s->filename)
                 return NULL;
 
 
             if (!s->filename)
                 return NULL;
 
-            if (!pa_get_host_name(hn, sizeof(hn)))
+            if (!(id = pa_machine_id()))
                 return NULL;
 
                 return NULL;
 
-            pa_snprintf(c, l, "{%s}unix:%s", hn, s->filename);
+            pa_snprintf(c, l, "{%s}unix:%s", id, s->filename);
+            pa_xfree(id);
             return c;
         }
 
             return c;
         }