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