LCOV - code coverage report
Current view: top level - pulsecore - socket-util.c (source / functions) Hit Total Coverage
Test: lcov.out Lines: 0 95 0.0 %
Date: 2012-07-17 Functions: 0 10 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 78 0.0 %

           Branch data     Line data    Source code
       1                 :            : /***
       2                 :            :   This file is part of PulseAudio.
       3                 :            : 
       4                 :            :   Copyright 2004-2006 Lennart Poettering
       5                 :            :   Copyright 2004 Joe Marcus Clarke
       6                 :            :   Copyright 2006-2007 Pierre Ossman <ossman@cendio.se> for Cendio AB
       7                 :            : 
       8                 :            :   PulseAudio is free software; you can redistribute it and/or modify
       9                 :            :   it under the terms of the GNU Lesser General Public License as published
      10                 :            :   by the Free Software Foundation; either version 2.1 of the License,
      11                 :            :   or (at your option) any later version.
      12                 :            : 
      13                 :            :   PulseAudio is distributed in the hope that it will be useful, but
      14                 :            :   WITHOUT ANY WARRANTY; without even the implied warranty of
      15                 :            :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
      16                 :            :   General Public License for more details.
      17                 :            : 
      18                 :            :   You should have received a copy of the GNU Lesser General Public License
      19                 :            :   along with PulseAudio; if not, write to the Free Software
      20                 :            :   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
      21                 :            :   USA.
      22                 :            : ***/
      23                 :            : 
      24                 :            : #ifdef HAVE_CONFIG_H
      25                 :            : #include <config.h>
      26                 :            : #endif
      27                 :            : 
      28                 :            : #include <stdlib.h>
      29                 :            : #include <signal.h>
      30                 :            : #include <errno.h>
      31                 :            : #include <string.h>
      32                 :            : #include <stdio.h>
      33                 :            : #include <sys/types.h>
      34                 :            : #include <unistd.h>
      35                 :            : #include <sys/stat.h>
      36                 :            : 
      37                 :            : #ifdef HAVE_SYS_UN_H
      38                 :            : #include <sys/un.h>
      39                 :            : #endif
      40                 :            : #ifdef HAVE_NETINET_IN_H
      41                 :            : #include <netinet/in.h>
      42                 :            : #endif
      43                 :            : #ifdef HAVE_NETINET_IN_SYSTM_H
      44                 :            : #include <netinet/in_systm.h>
      45                 :            : #endif
      46                 :            : #ifdef HAVE_NETINET_IP_H
      47                 :            : #include <netinet/ip.h>
      48                 :            : #endif
      49                 :            : #ifdef HAVE_NETINET_TCP_H
      50                 :            : #include <netinet/tcp.h>
      51                 :            : #endif
      52                 :            : #ifdef HAVE_NETDB_H
      53                 :            : #include <netdb.h>
      54                 :            : #endif
      55                 :            : 
      56                 :            : #include <pulsecore/core-error.h>
      57                 :            : #include <pulsecore/core-util.h>
      58                 :            : #include <pulsecore/log.h>
      59                 :            : #include <pulsecore/macro.h>
      60                 :            : #include <pulsecore/socket.h>
      61                 :            : #include <pulsecore/arpa-inet.h>
      62                 :            : 
      63                 :            : #include "socket-util.h"
      64                 :            : 
      65                 :          0 : void pa_socket_peer_to_string(int fd, char *c, size_t l) {
      66                 :            : #ifndef OS_IS_WIN32
      67                 :            :     struct stat st;
      68                 :            : #endif
      69                 :            : 
      70         [ #  # ]:          0 :     pa_assert(fd >= 0);
      71         [ #  # ]:          0 :     pa_assert(c);
      72         [ #  # ]:          0 :     pa_assert(l > 0);
      73                 :            : 
      74                 :            : #ifndef OS_IS_WIN32
      75         [ #  # ]:          0 :     pa_assert_se(fstat(fd, &st) == 0);
      76                 :            : 
      77         [ #  # ]:          0 :     if (S_ISSOCK(st.st_mode))
      78                 :            : #endif
      79                 :            :     {
      80                 :            :         union {
      81                 :            :             struct sockaddr_storage storage;
      82                 :            :             struct sockaddr sa;
      83                 :            :             struct sockaddr_in in;
      84                 :            : #ifdef HAVE_IPV6
      85                 :            :             struct sockaddr_in6 in6;
      86                 :            : #endif
      87                 :            : #ifdef HAVE_SYS_UN_H
      88                 :            :             struct sockaddr_un un;
      89                 :            : #endif
      90                 :            :         } sa;
      91                 :          0 :         socklen_t sa_len = sizeof(sa);
      92                 :            : 
      93         [ #  # ]:          0 :         if (getpeername(fd, &sa.sa, &sa_len) >= 0) {
      94                 :            : 
      95         [ #  # ]:          0 :             if (sa.sa.sa_family == AF_INET) {
      96         [ #  # ]:          0 :                 uint32_t ip = ntohl(sa.in.sin_addr.s_addr);
      97                 :            : 
      98                 :          0 :                 pa_snprintf(c, l, "TCP/IP client from %i.%i.%i.%i:%u",
      99                 :            :                             ip >> 24,
     100                 :          0 :                             (ip >> 16) & 0xFF,
     101                 :          0 :                             (ip >> 8) & 0xFF,
     102                 :            :                             ip & 0xFF,
     103         [ #  # ]:          0 :                             ntohs(sa.in.sin_port));
     104                 :          0 :                 return;
     105                 :            : #ifdef HAVE_IPV6
     106         [ #  # ]:          0 :             } else if (sa.sa.sa_family == AF_INET6) {
     107                 :            :                 char buf[INET6_ADDRSTRLEN];
     108                 :            :                 const char *res;
     109                 :            : 
     110                 :          0 :                 res = inet_ntop(AF_INET6, &sa.in6.sin6_addr, buf, sizeof(buf));
     111         [ #  # ]:          0 :                 if (res) {
     112         [ #  # ]:          0 :                     pa_snprintf(c, l, "TCP/IP client from [%s]:%u", buf, ntohs(sa.in6.sin6_port));
     113                 :          0 :                     return;
     114                 :            :                 }
     115                 :            : #endif
     116                 :            : #ifdef HAVE_SYS_UN_H
     117         [ #  # ]:          0 :             } else if (sa.sa.sa_family == AF_UNIX) {
     118                 :          0 :                 pa_snprintf(c, l, "UNIX socket client");
     119                 :          0 :                 return;
     120                 :            : #endif
     121                 :            :             }
     122                 :            :         }
     123                 :            : 
     124                 :          0 :         pa_snprintf(c, l, "Unknown network client");
     125                 :          0 :         return;
     126                 :            :     }
     127                 :            : #ifndef OS_IS_WIN32
     128         [ #  # ]:          0 :     else if (S_ISCHR(st.st_mode) && (fd == 0 || fd == 1)) {
     129                 :          0 :         pa_snprintf(c, l, "STDIN/STDOUT client");
     130                 :          0 :         return;
     131                 :            :     }
     132                 :            : #endif /* OS_IS_WIN32 */
     133                 :            : 
     134                 :          0 :     pa_snprintf(c, l, "Unknown client");
     135                 :            : }
     136                 :            : 
     137                 :          0 : void pa_make_socket_low_delay(int fd) {
     138                 :            : 
     139                 :            : #ifdef SO_PRIORITY
     140                 :            :     int priority;
     141         [ #  # ]:          0 :     pa_assert(fd >= 0);
     142                 :            : 
     143                 :          0 :     priority = 6;
     144         [ #  # ]:          0 :     if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (const void *) &priority, sizeof(priority)) < 0)
     145                 :          0 :         pa_log_warn("SO_PRIORITY failed: %s", pa_cstrerror(errno));
     146                 :            : #endif
     147                 :          0 : }
     148                 :            : 
     149                 :          0 : void pa_make_tcp_socket_low_delay(int fd) {
     150         [ #  # ]:          0 :     pa_assert(fd >= 0);
     151                 :            : 
     152                 :          0 :     pa_make_socket_low_delay(fd);
     153                 :            : 
     154                 :            : #if defined(SOL_TCP) || defined(IPPROTO_TCP)
     155                 :            :     {
     156                 :          0 :         int on = 1;
     157                 :            : #if defined(SOL_TCP)
     158         [ #  # ]:          0 :         if (setsockopt(fd, SOL_TCP, TCP_NODELAY, (const void *) &on, sizeof(on)) < 0)
     159                 :            : #else
     160                 :            :         if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const void *) &on, sizeof(on)) < 0)
     161                 :            : #endif
     162                 :          0 :             pa_log_warn("TCP_NODELAY failed: %s", pa_cstrerror(errno));
     163                 :            :     }
     164                 :            : #endif
     165                 :            : 
     166                 :            : #if defined(IPTOS_LOWDELAY) && defined(IP_TOS) && (defined(SOL_IP) || defined(IPPROTO_IP))
     167                 :            :     {
     168                 :          0 :         int tos = IPTOS_LOWDELAY;
     169                 :            : #ifdef SOL_IP
     170         [ #  # ]:          0 :         if (setsockopt(fd, SOL_IP, IP_TOS, (const void *) &tos, sizeof(tos)) < 0)
     171                 :            : #else
     172                 :            :         if (setsockopt(fd, IPPROTO_IP, IP_TOS, (const void *) &tos, sizeof(tos)) < 0)
     173                 :            : #endif
     174                 :          0 :             pa_log_warn("IP_TOS failed: %s", pa_cstrerror(errno));
     175                 :            :     }
     176                 :            : #endif
     177                 :          0 : }
     178                 :            : 
     179                 :          0 : void pa_make_udp_socket_low_delay(int fd) {
     180         [ #  # ]:          0 :     pa_assert(fd >= 0);
     181                 :            : 
     182                 :          0 :     pa_make_socket_low_delay(fd);
     183                 :            : 
     184                 :            : #if defined(IPTOS_LOWDELAY) && defined(IP_TOS) && (defined(SOL_IP) || defined(IPPROTO_IP))
     185                 :            :     {
     186                 :          0 :         int tos = IPTOS_LOWDELAY;
     187                 :            : #ifdef SOL_IP
     188         [ #  # ]:          0 :         if (setsockopt(fd, SOL_IP, IP_TOS, (const void *) &tos, sizeof(tos)) < 0)
     189                 :            : #else
     190                 :            :         if (setsockopt(fd, IPPROTO_IP, IP_TOS, (const void *) &tos, sizeof(tos)) < 0)
     191                 :            : #endif
     192                 :          0 :             pa_log_warn("IP_TOS failed: %s", pa_cstrerror(errno));
     193                 :            :     }
     194                 :            : #endif
     195                 :          0 : }
     196                 :            : 
     197                 :          0 : int pa_socket_set_rcvbuf(int fd, size_t l) {
     198                 :          0 :     int bufsz = (int) l;
     199                 :            : 
     200         [ #  # ]:          0 :     pa_assert(fd >= 0);
     201                 :            : 
     202         [ #  # ]:          0 :     if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const void *) &bufsz, sizeof(bufsz)) < 0) {
     203                 :          0 :         pa_log_warn("SO_RCVBUF: %s", pa_cstrerror(errno));
     204                 :          0 :         return -1;
     205                 :            :     }
     206                 :            : 
     207                 :            :     return 0;
     208                 :            : }
     209                 :            : 
     210                 :          0 : int pa_socket_set_sndbuf(int fd, size_t l) {
     211                 :          0 :     int bufsz = (int) l;
     212                 :            : 
     213         [ #  # ]:          0 :     pa_assert(fd >= 0);
     214                 :            : 
     215         [ #  # ]:          0 :     if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &bufsz, sizeof(bufsz)) < 0) {
     216                 :          0 :         pa_log_warn("SO_SNDBUF: %s", pa_cstrerror(errno));
     217                 :          0 :         return -1;
     218                 :            :     }
     219                 :            : 
     220                 :            :     return 0;
     221                 :            : }
     222                 :            : 
     223                 :            : #ifdef HAVE_SYS_UN_H
     224                 :            : 
     225                 :          0 : int pa_unix_socket_is_stale(const char *fn) {
     226                 :            :     struct sockaddr_un sa;
     227                 :          0 :     int fd = -1, ret = -1;
     228                 :            : 
     229         [ #  # ]:          0 :     pa_assert(fn);
     230                 :            : 
     231         [ #  # ]:          0 :     if ((fd = pa_socket_cloexec(PF_UNIX, SOCK_STREAM, 0)) < 0) {
     232                 :          0 :         pa_log("socket(): %s", pa_cstrerror(errno));
     233                 :          0 :         goto finish;
     234                 :            :     }
     235                 :            : 
     236                 :          0 :     sa.sun_family = AF_UNIX;
     237                 :            :     strncpy(sa.sun_path, fn, sizeof(sa.sun_path)-1);
     238                 :          0 :     sa.sun_path[sizeof(sa.sun_path) - 1] = 0;
     239                 :            : 
     240         [ #  # ]:          0 :     if (connect(fd, (struct sockaddr*) &sa, sizeof(sa)) < 0) {
     241         [ #  # ]:          0 :         if (errno == ECONNREFUSED)
     242                 :          0 :             ret = 1;
     243                 :            :     } else
     244                 :            :         ret = 0;
     245                 :            : 
     246                 :            : finish:
     247         [ #  # ]:          0 :     if (fd >= 0)
     248                 :          0 :         pa_close(fd);
     249                 :            : 
     250                 :          0 :     return ret;
     251                 :            : }
     252                 :            : 
     253                 :          0 : int pa_unix_socket_remove_stale(const char *fn) {
     254                 :            :     int r;
     255                 :            : 
     256         [ #  # ]:          0 :     pa_assert(fn);
     257                 :            : 
     258         [ #  # ]:          0 :     if ((r = pa_unix_socket_is_stale(fn)) < 0)
     259         [ #  # ]:          0 :         return errno != ENOENT ? -1 : 0;
     260                 :            : 
     261         [ #  # ]:          0 :     if (!r)
     262                 :            :         return 0;
     263                 :            : 
     264                 :            :     /* Yes, here is a race condition. But who cares? */
     265         [ #  # ]:          0 :     if (unlink(fn) < 0)
     266                 :            :         return -1;
     267                 :            : 
     268                 :          0 :     return 0;
     269                 :            : }
     270                 :            : 
     271                 :            : #else /* HAVE_SYS_UN_H */
     272                 :            : 
     273                 :            : int pa_unix_socket_is_stale(const char *fn) {
     274                 :            :     return -1;
     275                 :            : }
     276                 :            : 
     277                 :            : int pa_unix_socket_remove_stale(const char *fn) {
     278                 :            :     return -1;
     279                 :            : }
     280                 :            : 
     281                 :            : #endif /* HAVE_SYS_UN_H */
     282                 :            : 
     283                 :            : 
     284                 :          0 : pa_bool_t pa_socket_address_is_local(const struct sockaddr *sa) {
     285         [ #  # ]:          0 :     pa_assert(sa);
     286                 :            : 
     287   [ #  #  #  # ]:          0 :     switch (sa->sa_family) {
     288                 :            :         case AF_UNIX:
     289                 :            :             return TRUE;
     290                 :            : 
     291                 :            :         case AF_INET:
     292                 :          0 :             return ((const struct sockaddr_in*) sa)->sin_addr.s_addr == INADDR_LOOPBACK;
     293                 :            : 
     294                 :            : #ifdef HAVE_IPV6
     295                 :            :         case AF_INET6:
     296                 :          0 :             return memcmp(&((const struct sockaddr_in6*) sa)->sin6_addr, &in6addr_loopback, sizeof(struct in6_addr)) == 0;
     297                 :            : #endif
     298                 :            : 
     299                 :            :         default:
     300                 :          0 :             return FALSE;
     301                 :            :     }
     302                 :            : }
     303                 :            : 
     304                 :          0 : pa_bool_t pa_socket_is_local(int fd) {
     305                 :            : 
     306                 :            :     union {
     307                 :            :         struct sockaddr_storage storage;
     308                 :            :         struct sockaddr sa;
     309                 :            :         struct sockaddr_in in;
     310                 :            : #ifdef HAVE_IPV6
     311                 :            :         struct sockaddr_in6 in6;
     312                 :            : #endif
     313                 :            : #ifdef HAVE_SYS_UN_H
     314                 :            :         struct sockaddr_un un;
     315                 :            : #endif
     316                 :            :     } sa;
     317                 :          0 :     socklen_t sa_len = sizeof(sa);
     318                 :            : 
     319         [ #  # ]:          0 :     if (getpeername(fd, &sa.sa, &sa_len) < 0)
     320                 :            :         return FALSE;
     321                 :            : 
     322                 :          0 :     return pa_socket_address_is_local(&sa.sa);
     323                 :            : }

Generated by: LCOV version 1.9