LCOV - code coverage report
Current view: top level - pulsecore - socket-client.c (source / functions) Hit Total Coverage
Test: lcov.out Lines: 0 216 0.0 %
Date: 2012-07-17 Functions: 0 20 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 183 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 2006-2007 Pierre Ossman <ossman@cendio.se> for Cendio AB
       6                 :            : 
       7                 :            :     PulseAudio is free software; you can redistribute it and/or modify
       8                 :            :     it under the terms of the GNU Lesser General Public License as
       9                 :            :     published by the Free Software Foundation; either version 2.1 of the
      10                 :            :     License, or (at your option) any later version.
      11                 :            : 
      12                 :            :     PulseAudio is distributed in the hope that it will be useful, but
      13                 :            :     WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :            :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
      15                 :            :     Lesser General Public License for more details.
      16                 :            : 
      17                 :            :     You should have received a copy of the GNU Lesser General Public
      18                 :            :     License along with PulseAudio; if not, write to the Free Software
      19                 :            :     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
      20                 :            :     USA.
      21                 :            : ***/
      22                 :            : 
      23                 :            : #ifdef HAVE_CONFIG_H
      24                 :            : #include <config.h>
      25                 :            : #endif
      26                 :            : 
      27                 :            : /* #undef HAVE_LIBASYNCNS */
      28                 :            : 
      29                 :            : #include <unistd.h>
      30                 :            : #include <stdio.h>
      31                 :            : #include <errno.h>
      32                 :            : #include <string.h>
      33                 :            : #include <stdlib.h>
      34                 :            : 
      35                 :            : #ifdef HAVE_SYS_UN_H
      36                 :            : #include <sys/un.h>
      37                 :            : #endif
      38                 :            : #ifdef HAVE_NETINET_IN_H
      39                 :            : #include <netinet/in.h>
      40                 :            : #endif
      41                 :            : #ifdef HAVE_NETDB_H
      42                 :            : #include <netdb.h>
      43                 :            : #endif
      44                 :            : 
      45                 :            : #ifdef HAVE_LIBASYNCNS
      46                 :            : #include <asyncns.h>
      47                 :            : #endif
      48                 :            : 
      49                 :            : #include <pulse/rtclock.h>
      50                 :            : #include <pulse/timeval.h>
      51                 :            : #include <pulse/xmalloc.h>
      52                 :            : 
      53                 :            : #include <pulsecore/socket.h>
      54                 :            : #include <pulsecore/socket-util.h>
      55                 :            : #include <pulsecore/core-error.h>
      56                 :            : #include <pulsecore/core-rtclock.h>
      57                 :            : #include <pulsecore/core-util.h>
      58                 :            : #include <pulsecore/socket-util.h>
      59                 :            : #include <pulsecore/log.h>
      60                 :            : #include <pulsecore/parseaddr.h>
      61                 :            : #include <pulsecore/macro.h>
      62                 :            : #include <pulsecore/refcnt.h>
      63                 :            : #include <pulsecore/arpa-inet.h>
      64                 :            : 
      65                 :            : #include "socket-client.h"
      66                 :            : 
      67                 :            : #define CONNECT_TIMEOUT 5
      68                 :            : 
      69                 :            : struct pa_socket_client {
      70                 :            :     PA_REFCNT_DECLARE;
      71                 :            :     int fd;
      72                 :            : 
      73                 :            :     pa_mainloop_api *mainloop;
      74                 :            :     pa_io_event *io_event;
      75                 :            :     pa_time_event *timeout_event;
      76                 :            :     pa_defer_event *defer_event;
      77                 :            : 
      78                 :            :     pa_socket_client_cb_t callback;
      79                 :            :     void *userdata;
      80                 :            : 
      81                 :            :     pa_bool_t local;
      82                 :            : 
      83                 :            : #ifdef HAVE_LIBASYNCNS
      84                 :            :     asyncns_t *asyncns;
      85                 :            :     asyncns_query_t * asyncns_query;
      86                 :            :     pa_io_event *asyncns_io_event;
      87                 :            : #endif
      88                 :            : };
      89                 :            : 
      90                 :          0 : static pa_socket_client* socket_client_new(pa_mainloop_api *m) {
      91                 :            :     pa_socket_client *c;
      92         [ #  # ]:          0 :     pa_assert(m);
      93                 :            : 
      94                 :          0 :     c = pa_xnew0(pa_socket_client, 1);
      95                 :          0 :     PA_REFCNT_INIT(c);
      96                 :          0 :     c->mainloop = m;
      97                 :          0 :     c->fd = -1;
      98                 :            : 
      99                 :          0 :     return c;
     100                 :            : }
     101                 :            : 
     102                 :          0 : static void free_events(pa_socket_client *c) {
     103         [ #  # ]:          0 :     pa_assert(c);
     104                 :            : 
     105         [ #  # ]:          0 :     if (c->io_event) {
     106                 :          0 :         c->mainloop->io_free(c->io_event);
     107                 :          0 :         c->io_event = NULL;
     108                 :            :     }
     109                 :            : 
     110         [ #  # ]:          0 :     if (c->timeout_event) {
     111                 :          0 :         c->mainloop->time_free(c->timeout_event);
     112                 :          0 :         c->timeout_event = NULL;
     113                 :            :     }
     114                 :            : 
     115         [ #  # ]:          0 :     if (c->defer_event) {
     116                 :          0 :         c->mainloop->defer_free(c->defer_event);
     117                 :          0 :         c->defer_event = NULL;
     118                 :            :     }
     119                 :          0 : }
     120                 :            : 
     121                 :          0 : static void do_call(pa_socket_client *c) {
     122                 :          0 :     pa_iochannel *io = NULL;
     123                 :            :     int error;
     124                 :            :     socklen_t lerror;
     125                 :            : 
     126         [ #  # ]:          0 :     pa_assert(c);
     127         [ #  # ]:          0 :     pa_assert(PA_REFCNT_VALUE(c) >= 1);
     128         [ #  # ]:          0 :     pa_assert(c->callback);
     129                 :            : 
     130                 :          0 :     pa_socket_client_ref(c);
     131                 :            : 
     132         [ #  # ]:          0 :     if (c->fd < 0)
     133                 :            :         goto finish;
     134                 :            : 
     135                 :          0 :     lerror = sizeof(error);
     136         [ #  # ]:          0 :     if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void*)&error, &lerror) < 0) {
     137                 :          0 :         pa_log("getsockopt(): %s", pa_cstrerror(errno));
     138                 :          0 :         goto finish;
     139                 :            :     }
     140                 :            : 
     141         [ #  # ]:          0 :     if (lerror != sizeof(error)) {
     142                 :          0 :         pa_log("getsockopt() returned invalid size.");
     143                 :          0 :         goto finish;
     144                 :            :     }
     145                 :            : 
     146         [ #  # ]:          0 :     if (error != 0) {
     147                 :          0 :         pa_log_debug("connect(): %s", pa_cstrerror(error));
     148                 :          0 :         errno = error;
     149                 :          0 :         goto finish;
     150                 :            :     }
     151                 :            : 
     152                 :          0 :     io = pa_iochannel_new(c->mainloop, c->fd, c->fd);
     153                 :            : 
     154                 :            : finish:
     155 [ #  # ][ #  # ]:          0 :     if (!io && c->fd >= 0)
     156                 :          0 :         pa_close(c->fd);
     157                 :          0 :     c->fd = -1;
     158                 :            : 
     159                 :          0 :     free_events(c);
     160                 :            : 
     161                 :          0 :     c->callback(c, io, c->userdata);
     162                 :            : 
     163                 :          0 :     pa_socket_client_unref(c);
     164                 :          0 : }
     165                 :            : 
     166                 :          0 : static void connect_defer_cb(pa_mainloop_api *m, pa_defer_event *e, void *userdata) {
     167                 :          0 :     pa_socket_client *c = userdata;
     168                 :            : 
     169         [ #  # ]:          0 :     pa_assert(m);
     170         [ #  # ]:          0 :     pa_assert(c);
     171         [ #  # ]:          0 :     pa_assert(PA_REFCNT_VALUE(c) >= 1);
     172         [ #  # ]:          0 :     pa_assert(c->defer_event == e);
     173                 :            : 
     174                 :          0 :     do_call(c);
     175                 :          0 : }
     176                 :            : 
     177                 :          0 : static void connect_io_cb(pa_mainloop_api*m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {
     178                 :          0 :     pa_socket_client *c = userdata;
     179                 :            : 
     180         [ #  # ]:          0 :     pa_assert(m);
     181         [ #  # ]:          0 :     pa_assert(c);
     182         [ #  # ]:          0 :     pa_assert(PA_REFCNT_VALUE(c) >= 1);
     183         [ #  # ]:          0 :     pa_assert(c->io_event == e);
     184         [ #  # ]:          0 :     pa_assert(fd >= 0);
     185                 :            : 
     186                 :          0 :     do_call(c);
     187                 :          0 : }
     188                 :            : 
     189                 :          0 : static int do_connect(pa_socket_client *c, const struct sockaddr *sa, socklen_t len) {
     190         [ #  # ]:          0 :     pa_assert(c);
     191         [ #  # ]:          0 :     pa_assert(PA_REFCNT_VALUE(c) >= 1);
     192         [ #  # ]:          0 :     pa_assert(sa);
     193         [ #  # ]:          0 :     pa_assert(len > 0);
     194                 :            : 
     195                 :          0 :     pa_make_fd_nonblock(c->fd);
     196                 :            : 
     197         [ #  # ]:          0 :     if (connect(c->fd, sa, len) < 0) {
     198                 :            : #ifdef OS_IS_WIN32
     199                 :            :         if (WSAGetLastError() != EWOULDBLOCK) {
     200                 :            :             pa_log_debug("connect(): %d", WSAGetLastError());
     201                 :            : #else
     202         [ #  # ]:          0 :         if (errno != EINPROGRESS) {
     203                 :          0 :             pa_log_debug("connect(): %s (%d)", pa_cstrerror(errno), errno);
     204                 :            : #endif
     205                 :          0 :             return -1;
     206                 :            :         }
     207                 :            : 
     208                 :          0 :         c->io_event = c->mainloop->io_new(c->mainloop, c->fd, PA_IO_EVENT_OUTPUT, connect_io_cb, c);
     209                 :            :     } else
     210                 :          0 :         c->defer_event = c->mainloop->defer_new(c->mainloop, connect_defer_cb, c);
     211                 :            : 
     212                 :            :     return 0;
     213                 :            : }
     214                 :            : 
     215                 :          0 : pa_socket_client* pa_socket_client_new_ipv4(pa_mainloop_api *m, uint32_t address, uint16_t port) {
     216                 :            :     struct sockaddr_in sa;
     217                 :            : 
     218         [ #  # ]:          0 :     pa_assert(m);
     219         [ #  # ]:          0 :     pa_assert(port > 0);
     220                 :            : 
     221                 :            :     pa_zero(sa);
     222                 :          0 :     sa.sin_family = AF_INET;
     223         [ #  # ]:          0 :     sa.sin_port = htons(port);
     224         [ #  # ]:          0 :     sa.sin_addr.s_addr = htonl(address);
     225                 :            : 
     226                 :          0 :     return pa_socket_client_new_sockaddr(m, (struct sockaddr*) &sa, sizeof(sa));
     227                 :            : }
     228                 :            : 
     229                 :            : 
     230                 :          0 : pa_socket_client* pa_socket_client_new_unix(pa_mainloop_api *m, const char *filename) {
     231                 :            : #ifdef HAVE_SYS_UN_H
     232                 :            :     struct sockaddr_un sa;
     233                 :            : 
     234         [ #  # ]:          0 :     pa_assert(m);
     235         [ #  # ]:          0 :     pa_assert(filename);
     236                 :            : 
     237                 :            :     pa_zero(sa);
     238                 :          0 :     sa.sun_family = AF_UNIX;
     239                 :          0 :     pa_strlcpy(sa.sun_path, filename, sizeof(sa.sun_path));
     240                 :            : 
     241                 :          0 :     return pa_socket_client_new_sockaddr(m, (struct sockaddr*) &sa, sizeof(sa));
     242                 :            : #else /* HAVE_SYS_UN_H */
     243                 :            : 
     244                 :            :     return NULL;
     245                 :            : #endif /* HAVE_SYS_UN_H */
     246                 :            : }
     247                 :            : 
     248                 :          0 : static int sockaddr_prepare(pa_socket_client *c, const struct sockaddr *sa, size_t salen) {
     249         [ #  # ]:          0 :     pa_assert(c);
     250         [ #  # ]:          0 :     pa_assert(sa);
     251         [ #  # ]:          0 :     pa_assert(salen);
     252                 :            : 
     253                 :          0 :     c->local = pa_socket_address_is_local(sa);
     254                 :            : 
     255         [ #  # ]:          0 :     if ((c->fd = pa_socket_cloexec(sa->sa_family, SOCK_STREAM, 0)) < 0) {
     256                 :          0 :         pa_log("socket(): %s", pa_cstrerror(errno));
     257                 :          0 :         return -1;
     258                 :            :     }
     259                 :            : 
     260                 :            : #ifdef HAVE_IPV6
     261         [ #  # ]:          0 :     if (sa->sa_family == AF_INET || sa->sa_family == AF_INET6)
     262                 :            : #else
     263                 :            :     if (sa->sa_family == AF_INET)
     264                 :            : #endif
     265                 :          0 :         pa_make_tcp_socket_low_delay(c->fd);
     266                 :            :     else
     267                 :          0 :         pa_make_socket_low_delay(c->fd);
     268                 :            : 
     269         [ #  # ]:          0 :     if (do_connect(c, sa, (socklen_t) salen) < 0)
     270                 :            :         return -1;
     271                 :            : 
     272                 :          0 :     return 0;
     273                 :            : }
     274                 :            : 
     275                 :          0 : pa_socket_client* pa_socket_client_new_sockaddr(pa_mainloop_api *m, const struct sockaddr *sa, size_t salen) {
     276                 :            :     pa_socket_client *c;
     277                 :            : 
     278         [ #  # ]:          0 :     pa_assert(m);
     279         [ #  # ]:          0 :     pa_assert(sa);
     280         [ #  # ]:          0 :     pa_assert(salen > 0);
     281                 :            : 
     282                 :          0 :     c = socket_client_new(m);
     283                 :            : 
     284         [ #  # ]:          0 :     if (sockaddr_prepare(c, sa, salen) < 0)
     285                 :            :         goto fail;
     286                 :            : 
     287                 :            :     return c;
     288                 :            : 
     289                 :            : fail:
     290                 :          0 :     pa_socket_client_unref(c);
     291                 :          0 :     return NULL;
     292                 :            : }
     293                 :            : 
     294                 :          0 : static void socket_client_free(pa_socket_client *c) {
     295         [ #  # ]:          0 :     pa_assert(c);
     296         [ #  # ]:          0 :     pa_assert(c->mainloop);
     297                 :            : 
     298                 :          0 :     free_events(c);
     299                 :            : 
     300         [ #  # ]:          0 :     if (c->fd >= 0)
     301                 :          0 :         pa_close(c->fd);
     302                 :            : 
     303                 :            : #ifdef HAVE_LIBASYNCNS
     304         [ #  # ]:          0 :     if (c->asyncns_query)
     305                 :          0 :         asyncns_cancel(c->asyncns, c->asyncns_query);
     306         [ #  # ]:          0 :     if (c->asyncns)
     307                 :          0 :         asyncns_free(c->asyncns);
     308         [ #  # ]:          0 :     if (c->asyncns_io_event)
     309                 :          0 :         c->mainloop->io_free(c->asyncns_io_event);
     310                 :            : #endif
     311                 :            : 
     312                 :          0 :     pa_xfree(c);
     313                 :          0 : }
     314                 :            : 
     315                 :          0 : void pa_socket_client_unref(pa_socket_client *c) {
     316         [ #  # ]:          0 :     pa_assert(c);
     317         [ #  # ]:          0 :     pa_assert(PA_REFCNT_VALUE(c) >= 1);
     318                 :            : 
     319         [ #  # ]:          0 :     if (PA_REFCNT_DEC(c) <= 0)
     320                 :          0 :         socket_client_free(c);
     321                 :          0 : }
     322                 :            : 
     323                 :          0 : pa_socket_client* pa_socket_client_ref(pa_socket_client *c) {
     324         [ #  # ]:          0 :     pa_assert(c);
     325         [ #  # ]:          0 :     pa_assert(PA_REFCNT_VALUE(c) >= 1);
     326                 :            : 
     327                 :          0 :     PA_REFCNT_INC(c);
     328                 :          0 :     return c;
     329                 :            : }
     330                 :            : 
     331                 :          0 : void pa_socket_client_set_callback(pa_socket_client *c, pa_socket_client_cb_t on_connection, void *userdata) {
     332         [ #  # ]:          0 :     pa_assert(c);
     333         [ #  # ]:          0 :     pa_assert(PA_REFCNT_VALUE(c) >= 1);
     334                 :            : 
     335                 :          0 :     c->callback = on_connection;
     336                 :          0 :     c->userdata = userdata;
     337                 :          0 : }
     338                 :            : 
     339                 :          0 : pa_socket_client* pa_socket_client_new_ipv6(pa_mainloop_api *m, uint8_t address[16], uint16_t port) {
     340                 :            : #ifdef HAVE_IPV6
     341                 :            :     struct sockaddr_in6 sa;
     342                 :            : 
     343         [ #  # ]:          0 :     pa_assert(m);
     344         [ #  # ]:          0 :     pa_assert(address);
     345         [ #  # ]:          0 :     pa_assert(port > 0);
     346                 :            : 
     347                 :            :     pa_zero(sa);
     348                 :          0 :     sa.sin6_family = AF_INET6;
     349         [ #  # ]:          0 :     sa.sin6_port = htons(port);
     350                 :          0 :     memcpy(&sa.sin6_addr, address, sizeof(sa.sin6_addr));
     351                 :            : 
     352                 :          0 :     return pa_socket_client_new_sockaddr(m, (struct sockaddr*) &sa, sizeof(sa));
     353                 :            : 
     354                 :            : #else
     355                 :            :     return NULL;
     356                 :            : #endif
     357                 :            : }
     358                 :            : 
     359                 :            : #ifdef HAVE_LIBASYNCNS
     360                 :            : 
     361                 :          0 : static void asyncns_cb(pa_mainloop_api*m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {
     362                 :          0 :     pa_socket_client *c = userdata;
     363                 :          0 :     struct addrinfo *res = NULL;
     364                 :            :     int ret;
     365                 :            : 
     366         [ #  # ]:          0 :     pa_assert(m);
     367         [ #  # ]:          0 :     pa_assert(c);
     368         [ #  # ]:          0 :     pa_assert(PA_REFCNT_VALUE(c) >= 1);
     369         [ #  # ]:          0 :     pa_assert(c->asyncns_io_event == e);
     370         [ #  # ]:          0 :     pa_assert(fd >= 0);
     371                 :            : 
     372         [ #  # ]:          0 :     if (asyncns_wait(c->asyncns, 0) < 0)
     373                 :            :         goto fail;
     374                 :            : 
     375         [ #  # ]:          0 :     if (!asyncns_isdone(c->asyncns, c->asyncns_query))
     376                 :            :         return;
     377                 :            : 
     378                 :          0 :     ret = asyncns_getaddrinfo_done(c->asyncns, c->asyncns_query, &res);
     379                 :          0 :     c->asyncns_query = NULL;
     380                 :            : 
     381 [ #  # ][ #  # ]:          0 :     if (ret != 0 || !res)
     382                 :            :         goto fail;
     383                 :            : 
     384         [ #  # ]:          0 :     if (res->ai_addr)
     385         [ #  # ]:          0 :         if (sockaddr_prepare(c, res->ai_addr, res->ai_addrlen) < 0)
     386                 :            :             goto fail;
     387                 :            : 
     388                 :          0 :     asyncns_freeaddrinfo(res);
     389                 :            : 
     390                 :          0 :     m->io_free(c->asyncns_io_event);
     391                 :          0 :     c->asyncns_io_event = NULL;
     392                 :          0 :     return;
     393                 :            : 
     394                 :            : fail:
     395                 :          0 :     m->io_free(c->asyncns_io_event);
     396                 :          0 :     c->asyncns_io_event = NULL;
     397                 :            : 
     398                 :          0 :     errno = EHOSTUNREACH;
     399                 :          0 :     do_call(c);
     400                 :          0 :     return;
     401                 :            : 
     402                 :            : }
     403                 :            : 
     404                 :            : #endif
     405                 :            : 
     406                 :          0 : static void timeout_cb(pa_mainloop_api *m, pa_time_event *e, const struct timeval *t, void *userdata) {
     407                 :          0 :     pa_socket_client *c = userdata;
     408                 :            : 
     409         [ #  # ]:          0 :     pa_assert(m);
     410         [ #  # ]:          0 :     pa_assert(e);
     411         [ #  # ]:          0 :     pa_assert(c);
     412                 :            : 
     413         [ #  # ]:          0 :     if (c->fd >= 0) {
     414                 :          0 :         pa_close(c->fd);
     415                 :          0 :         c->fd = -1;
     416                 :            :     }
     417                 :            : 
     418                 :          0 :     errno = ETIMEDOUT;
     419                 :          0 :     do_call(c);
     420                 :          0 : }
     421                 :            : 
     422                 :          0 : static void start_timeout(pa_socket_client *c, pa_bool_t use_rtclock) {
     423                 :            :     struct timeval tv;
     424                 :            : 
     425         [ #  # ]:          0 :     pa_assert(c);
     426         [ #  # ]:          0 :     pa_assert(!c->timeout_event);
     427                 :            : 
     428                 :          0 :     c->timeout_event = c->mainloop->time_new(c->mainloop, pa_timeval_rtstore(&tv, pa_rtclock_now() + CONNECT_TIMEOUT * PA_USEC_PER_SEC, use_rtclock), timeout_cb, c);
     429                 :          0 : }
     430                 :            : 
     431                 :          0 : pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, pa_bool_t use_rtclock, const char*name, uint16_t default_port) {
     432                 :          0 :     pa_socket_client *c = NULL;
     433                 :            :     pa_parsed_address a;
     434                 :            : 
     435         [ #  # ]:          0 :     pa_assert(m);
     436         [ #  # ]:          0 :     pa_assert(name);
     437                 :            : 
     438         [ #  # ]:          0 :     if (pa_parse_address(name, &a) < 0)
     439                 :            :         return NULL;
     440                 :            : 
     441         [ #  # ]:          0 :     if (!a.port)
     442                 :          0 :         a.port = default_port;
     443                 :            : 
     444      [ #  #  # ]:          0 :     switch (a.type) {
     445                 :            :         case PA_PARSED_ADDRESS_UNIX:
     446         [ #  # ]:          0 :             if ((c = pa_socket_client_new_unix(m, a.path_or_host)))
     447                 :          0 :                 start_timeout(c, use_rtclock);
     448                 :            :             break;
     449                 :            : 
     450                 :            :         case PA_PARSED_ADDRESS_TCP4:  /* Fallthrough */
     451                 :            :         case PA_PARSED_ADDRESS_TCP6:  /* Fallthrough */
     452                 :            :         case PA_PARSED_ADDRESS_TCP_AUTO: {
     453                 :            :             struct addrinfo hints;
     454                 :            :             char port[12];
     455                 :            : 
     456                 :          0 :             pa_snprintf(port, sizeof(port), "%u", (unsigned) a.port);
     457                 :            : 
     458                 :            :             pa_zero(hints);
     459         [ #  # ]:          0 :             if (a.type == PA_PARSED_ADDRESS_TCP4)
     460                 :          0 :                 hints.ai_family = PF_INET;
     461                 :            : #ifdef HAVE_IPV6
     462         [ #  # ]:          0 :             else if (a.type == PA_PARSED_ADDRESS_TCP6)
     463                 :          0 :                 hints.ai_family = PF_INET6;
     464                 :            : #endif
     465                 :            :             else
     466                 :          0 :                 hints.ai_family = PF_UNSPEC;
     467                 :            : 
     468                 :          0 :             hints.ai_socktype = SOCK_STREAM;
     469                 :            : 
     470                 :            : #if defined(HAVE_LIBASYNCNS)
     471                 :            :             {
     472                 :            :                 asyncns_t *asyncns;
     473                 :            : 
     474         [ #  # ]:          0 :                 if (!(asyncns = asyncns_new(1)))
     475                 :            :                     goto finish;
     476                 :            : 
     477                 :          0 :                 c = socket_client_new(m);
     478                 :          0 :                 c->asyncns = asyncns;
     479                 :          0 :                 c->asyncns_io_event = m->io_new(m, asyncns_fd(c->asyncns), PA_IO_EVENT_INPUT, asyncns_cb, c);
     480         [ #  # ]:          0 :                 pa_assert_se(c->asyncns_query = asyncns_getaddrinfo(c->asyncns, a.path_or_host, port, &hints));
     481                 :          0 :                 start_timeout(c, use_rtclock);
     482                 :            :             }
     483                 :            : #elif defined(HAVE_GETADDRINFO)
     484                 :            :             {
     485                 :            :                 int ret;
     486                 :            :                 struct addrinfo *res = NULL;
     487                 :            : 
     488                 :            :                 ret = getaddrinfo(a.path_or_host, port, &hints, &res);
     489                 :            : 
     490                 :            :                 if (ret < 0 || !res)
     491                 :            :                     goto finish;
     492                 :            : 
     493                 :            :                 if (res->ai_addr) {
     494                 :            :                     if ((c = pa_socket_client_new_sockaddr(m, res->ai_addr, res->ai_addrlen)))
     495                 :            :                         start_timeout(c, use_rtclock);
     496                 :            :                 }
     497                 :            : 
     498                 :            :                 freeaddrinfo(res);
     499                 :            :             }
     500                 :            : #else
     501                 :            :             {
     502                 :            :                 struct hostent *host = NULL;
     503                 :            :                 struct sockaddr_in s;
     504                 :            : 
     505                 :            : #ifdef HAVE_IPV6
     506                 :            :                 /* FIXME: PF_INET6 support */
     507                 :            :                 if (hints.ai_family == PF_INET6) {
     508                 :            :                     pa_log_error("IPv6 is not supported on Windows");
     509                 :            :                     goto finish;
     510                 :            :                 }
     511                 :            : #endif
     512                 :            : 
     513                 :            :                 host = gethostbyname(a.path_or_host);
     514                 :            :                 if (!host) {
     515                 :            :                     unsigned int addr = inet_addr(a.path_or_host);
     516                 :            :                     if (addr != INADDR_NONE)
     517                 :            :                         host = gethostbyaddr((char*)&addr, 4, AF_INET);
     518                 :            :                 }
     519                 :            : 
     520                 :            :                 if (!host)
     521                 :            :                     goto finish;
     522                 :            : 
     523                 :            :                 pa_zero(s);
     524                 :            :                 s.sin_family = AF_INET;
     525                 :            :                 memcpy(&s.sin_addr, host->h_addr, sizeof(struct in_addr));
     526                 :            :                 s.sin_port = htons(a.port);
     527                 :            : 
     528                 :            :                 if ((c = pa_socket_client_new_sockaddr(m, (struct sockaddr*)&s, sizeof(s))))
     529                 :            :                     start_timeout(c, use_rtclock);
     530                 :            :             }
     531                 :            : #endif /* HAVE_LIBASYNCNS */
     532                 :            :         }
     533                 :            :     }
     534                 :            : 
     535                 :            : finish:
     536                 :          0 :     pa_xfree(a.path_or_host);
     537                 :          0 :     return c;
     538                 :            : 
     539                 :            : }
     540                 :            : 
     541                 :            : /* Return non-zero when the target sockaddr is considered
     542                 :            :    local. "local" means UNIX socket or TCP socket on localhost. Other
     543                 :            :    local IP addresses are not considered local. */
     544                 :          0 : pa_bool_t pa_socket_client_is_local(pa_socket_client *c) {
     545         [ #  # ]:          0 :     pa_assert(c);
     546         [ #  # ]:          0 :     pa_assert(PA_REFCNT_VALUE(c) >= 1);
     547                 :            : 
     548                 :          0 :     return c->local;
     549                 :            : }

Generated by: LCOV version 1.9