]> code.delx.au - pulseaudio/blobdiff - src/pulsecore/socket-util.c
core: make cpuid code compile cleanly with 32bit PIC
[pulseaudio] / src / pulsecore / socket-util.c
index b7361e901629284b5ed919f226992fe671a7fb8d..2cc9882a1c63301a4a900f25afd7fff31509da42 100644 (file)
@@ -1,5 +1,3 @@
-/* $Id$ */
-
 /***
   This file is part of PulseAudio.
 
 /***
   This file is part of PulseAudio.
 
@@ -9,7 +7,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
@@ -87,15 +85,16 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) {
 
 #ifndef OS_IS_WIN32
     pa_assert_se(fstat(fd, &st) == 0);
 
 #ifndef OS_IS_WIN32
     pa_assert_se(fstat(fd, &st) == 0);
-#endif
 
 
-#ifndef OS_IS_WIN32
     if (S_ISSOCK(st.st_mode)) {
 #endif
         union {
     if (S_ISSOCK(st.st_mode)) {
 #endif
         union {
+            struct sockaddr_storage storage;
             struct sockaddr sa;
             struct sockaddr_in in;
             struct sockaddr sa;
             struct sockaddr_in in;
+#ifdef HAVE_IPV6
             struct sockaddr_in6 in6;
             struct sockaddr_in6 in6;
+#endif
 #ifdef HAVE_SYS_UN_H
             struct sockaddr_un un;
 #endif
 #ifdef HAVE_SYS_UN_H
             struct sockaddr_un un;
 #endif
@@ -114,6 +113,7 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) {
                             ip & 0xFF,
                             ntohs(sa.in.sin_port));
                 return;
                             ip & 0xFF,
                             ntohs(sa.in.sin_port));
                 return;
+#ifdef HAVE_IPV6
             } else if (sa.sa.sa_family == AF_INET6) {
                 char buf[INET6_ADDRSTRLEN];
                 const char *res;
             } else if (sa.sa.sa_family == AF_INET6) {
                 char buf[INET6_ADDRSTRLEN];
                 const char *res;
@@ -123,14 +123,15 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) {
                     pa_snprintf(c, l, "TCP/IP client from [%s]:%u", buf, ntohs(sa.in6.sin6_port));
                     return;
                 }
                     pa_snprintf(c, l, "TCP/IP client from [%s]:%u", buf, ntohs(sa.in6.sin6_port));
                     return;
                 }
+#endif
 #ifdef HAVE_SYS_UN_H
             } else if (sa.sa.sa_family == AF_UNIX) {
                 pa_snprintf(c, l, "UNIX socket client");
                 return;
 #endif
             }
 #ifdef HAVE_SYS_UN_H
             } else if (sa.sa.sa_family == AF_UNIX) {
                 pa_snprintf(c, l, "UNIX socket client");
                 return;
 #endif
             }
-
         }
         }
+
 #ifndef OS_IS_WIN32
         pa_snprintf(c, l, "Unknown network client");
         return;
 #ifndef OS_IS_WIN32
         pa_snprintf(c, l, "Unknown network client");
         return;
@@ -143,89 +144,72 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) {
     pa_snprintf(c, l, "Unknown client");
 }
 
     pa_snprintf(c, l, "Unknown client");
 }
 
-int pa_socket_low_delay(int fd) {
-    
+void pa_make_socket_low_delay(int fd) {
+
 #ifdef SO_PRIORITY
     int priority;
     pa_assert(fd >= 0);
 
     priority = 6;
 #ifdef SO_PRIORITY
     int priority;
     pa_assert(fd >= 0);
 
     priority = 6;
-    if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (void*)&priority, sizeof(priority)) < 0) {
+    if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority)) < 0)
         pa_log_warn("SO_PRIORITY failed: %s", pa_cstrerror(errno));
         pa_log_warn("SO_PRIORITY failed: %s", pa_cstrerror(errno));
-        return -1;
-    }
 #endif
 #endif
-
-    return 0;
 }
 
 }
 
-int pa_socket_tcp_low_delay(int fd) {
-    int ret, tos, on;
-
+void pa_make_tcp_socket_low_delay(int fd) {
     pa_assert(fd >= 0);
 
     pa_assert(fd >= 0);
 
-    ret = pa_socket_low_delay(fd);
-
-    on = 1;
-    tos = 0;
+    pa_make_socket_low_delay(fd);
 
 #if defined(SOL_TCP) || defined(IPPROTO_TCP)
 
 #if defined(SOL_TCP) || defined(IPPROTO_TCP)
+    {
+        int on = 1;
 #if defined(SOL_TCP)
 #if defined(SOL_TCP)
-    if (setsockopt(fd, SOL_TCP, TCP_NODELAY, (void*)&on, sizeof(on)) < 0)
+        if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
 #else
 #else
-    if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*)&on, sizeof(on)) < 0)
+        if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
 #endif
 #endif
-    {
-        pa_log_warn("TCP_NODELAY failed: %s", pa_cstrerror(errno));
-        ret = -1;
+            pa_log_warn("TCP_NODELAY failed: %s", pa_cstrerror(errno));
     }
 #endif
 
 #if defined(IPTOS_LOWDELAY) && defined(IP_TOS) && (defined(SOL_IP) || defined(IPPROTO_IP))
     }
 #endif
 
 #if defined(IPTOS_LOWDELAY) && defined(IP_TOS) && (defined(SOL_IP) || defined(IPPROTO_IP))
-    tos = IPTOS_LOWDELAY;
+    {
+        int tos = IPTOS_LOWDELAY;
 #ifdef SOL_IP
 #ifdef SOL_IP
-    if (setsockopt(fd, SOL_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0)
+        if (setsockopt(fd, SOL_IP, IP_TOS, &tos, sizeof(tos)) < 0)
 #else
 #else
-    if (setsockopt(fd, IPPROTO_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0)
+        if (setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0)
 #endif
 #endif
-    {
-        pa_log_warn("IP_TOS failed: %s", pa_cstrerror(errno));
-        ret = -1;
+            pa_log_warn("IP_TOS failed: %s", pa_cstrerror(errno));
     }
 #endif
     }
 #endif
-
-    return ret;
 }
 
 }
 
-int pa_socket_udp_low_delay(int fd) {
-    int ret, tos;
-
+void pa_make_udp_socket_low_delay(int fd) {
     pa_assert(fd >= 0);
 
     pa_assert(fd >= 0);
 
-    ret = pa_socket_low_delay(fd);
-
-    tos = 0;
+    pa_make_socket_low_delay(fd);
 
 #if defined(IPTOS_LOWDELAY) && defined(IP_TOS) && (defined(SOL_IP) || defined(IPPROTO_IP))
 
 #if defined(IPTOS_LOWDELAY) && defined(IP_TOS) && (defined(SOL_IP) || defined(IPPROTO_IP))
-    tos = IPTOS_LOWDELAY;
+    {
+        int tos = IPTOS_LOWDELAY;
 #ifdef SOL_IP
 #ifdef SOL_IP
-    if (setsockopt(fd, SOL_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0)
+        if (setsockopt(fd, SOL_IP, IP_TOS, &tos, sizeof(tos)) < 0)
 #else
 #else
-    if (setsockopt(fd, IPPROTO_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0)
+        if (setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0)
 #endif
 #endif
-    {
-        ret = -1;
-        pa_log_warn("IP_TOS failed: %s", pa_cstrerror(errno));
+            pa_log_warn("IP_TOS failed: %s", pa_cstrerror(errno));
     }
 #endif
     }
 #endif
-
-    return ret;
 }
 
 int pa_socket_set_rcvbuf(int fd, size_t l) {
 }
 
 int pa_socket_set_rcvbuf(int fd, size_t l) {
+    int bufsz = (int) l;
+
     pa_assert(fd >= 0);
 
     pa_assert(fd >= 0);
 
-    if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void*)&l, sizeof(l)) < 0) {
+    if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &bufsz, sizeof(bufsz)) < 0) {
         pa_log_warn("SO_RCVBUF: %s", pa_cstrerror(errno));
         return -1;
     }
         pa_log_warn("SO_RCVBUF: %s", pa_cstrerror(errno));
         return -1;
     }
@@ -234,10 +218,12 @@ int pa_socket_set_rcvbuf(int fd, size_t l) {
 }
 
 int pa_socket_set_sndbuf(int fd, size_t l) {
 }
 
 int pa_socket_set_sndbuf(int fd, size_t l) {
+    int bufsz = (int) l;
+
     pa_assert(fd >= 0);
 
     pa_assert(fd >= 0);
 
-    if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void*)&l, sizeof(l)) < 0) {
-        pa_log("SO_SNDBUF: %s", pa_cstrerror(errno));
+    if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &bufsz, sizeof(bufsz)) < 0) {
+        pa_log_warn("SO_SNDBUF: %s", pa_cstrerror(errno));
         return -1;
     }
 
         return -1;
     }
 
@@ -252,7 +238,7 @@ int pa_unix_socket_is_stale(const char *fn) {
 
     pa_assert(fn);
 
 
     pa_assert(fn);
 
-    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 finish;
     }
         pa_log("socket(): %s", pa_cstrerror(errno));
         goto finish;
     }
@@ -303,3 +289,45 @@ int pa_unix_socket_remove_stale(const char *fn) {
 }
 
 #endif /* HAVE_SYS_UN_H */
 }
 
 #endif /* HAVE_SYS_UN_H */
+
+
+pa_bool_t pa_socket_address_is_local(const struct sockaddr *sa) {
+    pa_assert(sa);
+
+    switch (sa->sa_family) {
+        case AF_UNIX:
+            return TRUE;
+
+        case AF_INET:
+            return ((const struct sockaddr_in*) sa)->sin_addr.s_addr == INADDR_LOOPBACK;
+
+#ifdef HAVE_IPV6
+        case AF_INET6:
+            return memcmp(&((const struct sockaddr_in6*) sa)->sin6_addr, &in6addr_loopback, sizeof(struct in6_addr)) == 0;
+#endif
+
+        default:
+            return FALSE;
+    }
+}
+
+pa_bool_t pa_socket_is_local(int fd) {
+
+    union {
+        struct sockaddr_storage storage;
+        struct sockaddr sa;
+        struct sockaddr_in in;
+#ifdef HAVE_IPV6
+        struct sockaddr_in6 in6;
+#endif
+#ifdef HAVE_SYS_UN_H
+        struct sockaddr_un un;
+#endif
+    } sa;
+    socklen_t sa_len = sizeof(sa);
+
+    if (getpeername(fd, &sa.sa, &sa_len) < 0)
+        return FALSE;
+
+    return pa_socket_address_is_local(&sa.sa);
+}