Merge commit 'origin/master-tx'
[profile/ivi/pulseaudio-panda.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/timeval.h>
56 #include <pulse/xmalloc.h>
57
58 #include <pulsecore/winsock.h>
59 #include <pulsecore/core-error.h>
60 #include <pulsecore/socket-util.h>
61 #include <pulsecore/core-util.h>
62 #include <pulsecore/socket-util.h>
63 #include <pulsecore/log.h>
64 #include <pulsecore/parseaddr.h>
65 #include <pulsecore/macro.h>
66 #include <pulsecore/refcnt.h>
67
68 #include "socket-client.h"
69
70 #define CONNECT_TIMEOUT 5
71
72 struct pa_socket_client {
73     PA_REFCNT_DECLARE;
74     pa_mainloop_api *mainloop;
75     int fd;
76     pa_io_event *io_event;
77     pa_time_event *timeout_event;
78     pa_defer_event *defer_event;
79     pa_socket_client_cb_t callback;
80     void *userdata;
81     pa_bool_t local;
82 #ifdef HAVE_LIBASYNCNS
83     asyncns_t *asyncns;
84     asyncns_query_t * asyncns_query;
85     pa_io_event *asyncns_io_event;
86 #endif
87 };
88
89 static pa_socket_client* socket_client_new(pa_mainloop_api *m) {
90     pa_socket_client *c;
91     pa_assert(m);
92
93     c = pa_xnew(pa_socket_client, 1);
94     PA_REFCNT_INIT(c);
95     c->mainloop = m;
96     c->fd = -1;
97     c->io_event = NULL;
98     c->timeout_event = NULL;
99     c->defer_event = NULL;
100     c->callback = NULL;
101     c->userdata = NULL;
102     c->local = FALSE;
103
104 #ifdef HAVE_LIBASYNCNS
105     c->asyncns = NULL;
106     c->asyncns_io_event = NULL;
107     c->asyncns_query = NULL;
108 #endif
109
110     return c;
111 }
112
113 static void free_events(pa_socket_client *c) {
114     pa_assert(c);
115
116     if (c->io_event) {
117         c->mainloop->io_free(c->io_event);
118         c->io_event = NULL;
119     }
120
121     if (c->timeout_event) {
122         c->mainloop->time_free(c->timeout_event);
123         c->timeout_event = NULL;
124     }
125
126     if (c->defer_event) {
127         c->mainloop->defer_free(c->defer_event);
128         c->defer_event = NULL;
129     }
130 }
131
132 static void do_call(pa_socket_client *c) {
133     pa_iochannel *io = NULL;
134     int error;
135     socklen_t lerror;
136
137     pa_assert(c);
138     pa_assert(PA_REFCNT_VALUE(c) >= 1);
139     pa_assert(c->callback);
140
141     pa_socket_client_ref(c);
142
143     if (c->fd < 0)
144         goto finish;
145
146     lerror = sizeof(error);
147     if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void*)&error, &lerror) < 0) {
148         pa_log("getsockopt(): %s", pa_cstrerror(errno));
149         goto finish;
150     }
151
152     if (lerror != sizeof(error)) {
153         pa_log("getsockopt() returned invalid size.");
154         goto finish;
155     }
156
157     if (error != 0) {
158         pa_log_debug("connect(): %s", pa_cstrerror(error));
159         errno = error;
160         goto finish;
161     }
162
163     io = pa_iochannel_new(c->mainloop, c->fd, c->fd);
164     pa_assert(io);
165
166 finish:
167     if (!io && c->fd >= 0)
168         pa_close(c->fd);
169     c->fd = -1;
170
171     free_events(c);
172
173     pa_assert(c->callback);
174     c->callback(c, io, c->userdata);
175
176     pa_socket_client_unref(c);
177 }
178
179 static void connect_defer_cb(pa_mainloop_api *m, pa_defer_event *e, void *userdata) {
180     pa_socket_client *c = userdata;
181
182     pa_assert(m);
183     pa_assert(c);
184     pa_assert(PA_REFCNT_VALUE(c) >= 1);
185     pa_assert(c->defer_event == e);
186
187     do_call(c);
188 }
189
190 static void connect_io_cb(pa_mainloop_api*m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {
191     pa_socket_client *c = userdata;
192
193     pa_assert(m);
194     pa_assert(c);
195     pa_assert(PA_REFCNT_VALUE(c) >= 1);
196     pa_assert(c->io_event == e);
197     pa_assert(fd >= 0);
198
199     do_call(c);
200 }
201
202 static int do_connect(pa_socket_client *c, const struct sockaddr *sa, socklen_t len) {
203     int r;
204
205     pa_assert(c);
206     pa_assert(PA_REFCNT_VALUE(c) >= 1);
207     pa_assert(sa);
208     pa_assert(len > 0);
209
210     pa_make_fd_nonblock(c->fd);
211
212     if ((r = connect(c->fd, sa, len)) < 0) {
213 #ifdef OS_IS_WIN32
214         if (WSAGetLastError() != EWOULDBLOCK) {
215             pa_log_debug("connect(): %d", WSAGetLastError());
216 #else
217         if (errno != EINPROGRESS) {
218             pa_log_debug("connect(): %s (%d)", pa_cstrerror(errno), errno);
219 #endif
220             return -1;
221         }
222
223         pa_assert_se(c->io_event = c->mainloop->io_new(c->mainloop, c->fd, PA_IO_EVENT_OUTPUT, connect_io_cb, c));
224     } else
225         pa_assert_se(c->defer_event = c->mainloop->defer_new(c->mainloop, connect_defer_cb, c));
226
227     return 0;
228 }
229
230 pa_socket_client* pa_socket_client_new_ipv4(pa_mainloop_api *m, uint32_t address, uint16_t port) {
231     struct sockaddr_in sa;
232
233     pa_assert(m);
234     pa_assert(port > 0);
235
236     memset(&sa, 0, sizeof(sa));
237     sa.sin_family = AF_INET;
238     sa.sin_port = htons(port);
239     sa.sin_addr.s_addr = htonl(address);
240
241     return pa_socket_client_new_sockaddr(m, (struct sockaddr*) &sa, sizeof(sa));
242 }
243
244 #ifdef HAVE_SYS_UN_H
245
246 pa_socket_client* pa_socket_client_new_unix(pa_mainloop_api *m, const char *filename) {
247     struct sockaddr_un sa;
248
249     pa_assert(m);
250     pa_assert(filename);
251
252     memset(&sa, 0, sizeof(sa));
253     sa.sun_family = AF_UNIX;
254     pa_strlcpy(sa.sun_path, filename, sizeof(sa.sun_path));
255
256     return pa_socket_client_new_sockaddr(m, (struct sockaddr*) &sa, sizeof(sa));
257 }
258
259 #else /* HAVE_SYS_UN_H */
260
261 pa_socket_client* pa_socket_client_new_unix(pa_mainloop_api *m, const char *filename) {
262     return NULL;
263 }
264
265 #endif /* HAVE_SYS_UN_H */
266
267 static int sockaddr_prepare(pa_socket_client *c, const struct sockaddr *sa, size_t salen) {
268     pa_assert(c);
269     pa_assert(sa);
270     pa_assert(salen);
271
272     c->local = pa_socket_address_is_local(sa);
273
274     if ((c->fd = socket(sa->sa_family, SOCK_STREAM, 0)) < 0) {
275         pa_log("socket(): %s", pa_cstrerror(errno));
276         return -1;
277     }
278
279     pa_make_fd_cloexec(c->fd);
280
281 #ifdef HAVE_IPV6
282     if (sa->sa_family == AF_INET || sa->sa_family == AF_INET6)
283 #else
284     if (sa->sa_family == AF_INET)
285 #endif
286         pa_make_tcp_socket_low_delay(c->fd);
287     else
288         pa_make_socket_low_delay(c->fd);
289
290     if (do_connect(c, sa, (socklen_t) salen) < 0)
291         return -1;
292
293     return 0;
294 }
295
296 pa_socket_client* pa_socket_client_new_sockaddr(pa_mainloop_api *m, const struct sockaddr *sa, size_t salen) {
297     pa_socket_client *c;
298
299     pa_assert(m);
300     pa_assert(sa);
301     pa_assert(salen > 0);
302
303     pa_assert_se(c = socket_client_new(m));
304
305     if (sockaddr_prepare(c, sa, salen) < 0)
306         goto fail;
307
308     return c;
309
310 fail:
311     pa_socket_client_unref(c);
312     return NULL;
313 }
314
315 static void socket_client_free(pa_socket_client *c) {
316     pa_assert(c);
317     pa_assert(c->mainloop);
318
319     free_events(c);
320
321     if (c->fd >= 0)
322         pa_close(c->fd);
323
324 #ifdef HAVE_LIBASYNCNS
325     if (c->asyncns_query)
326         asyncns_cancel(c->asyncns, c->asyncns_query);
327     if (c->asyncns)
328         asyncns_free(c->asyncns);
329     if (c->asyncns_io_event)
330         c->mainloop->io_free(c->asyncns_io_event);
331 #endif
332
333     pa_xfree(c);
334 }
335
336 void pa_socket_client_unref(pa_socket_client *c) {
337     pa_assert(c);
338     pa_assert(PA_REFCNT_VALUE(c) >= 1);
339
340     if (PA_REFCNT_DEC(c) <= 0)
341         socket_client_free(c);
342 }
343
344 pa_socket_client* pa_socket_client_ref(pa_socket_client *c) {
345     pa_assert(c);
346     pa_assert(PA_REFCNT_VALUE(c) >= 1);
347
348     PA_REFCNT_INC(c);
349     return c;
350 }
351
352 void pa_socket_client_set_callback(pa_socket_client *c, pa_socket_client_cb_t on_connection, void *userdata) {
353     pa_assert(c);
354     pa_assert(PA_REFCNT_VALUE(c) >= 1);
355
356     c->callback = on_connection;
357     c->userdata = userdata;
358 }
359
360 #ifdef HAVE_IPV6
361 pa_socket_client* pa_socket_client_new_ipv6(pa_mainloop_api *m, uint8_t address[16], uint16_t port) {
362     struct sockaddr_in6 sa;
363
364     pa_assert(m);
365     pa_assert(address);
366     pa_assert(port > 0);
367
368     memset(&sa, 0, sizeof(sa));
369     sa.sin6_family = AF_INET6;
370     sa.sin6_port = htons(port);
371     memcpy(&sa.sin6_addr, address, sizeof(sa.sin6_addr));
372
373     return pa_socket_client_new_sockaddr(m, (struct sockaddr*) &sa, sizeof(sa));
374 }
375 #endif
376
377 #ifdef HAVE_LIBASYNCNS
378
379 static void asyncns_cb(pa_mainloop_api*m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {
380     pa_socket_client *c = userdata;
381     struct addrinfo *res = NULL;
382     int ret;
383
384     pa_assert(m);
385     pa_assert(c);
386     pa_assert(PA_REFCNT_VALUE(c) >= 1);
387     pa_assert(c->asyncns_io_event == e);
388     pa_assert(fd >= 0);
389
390     if (asyncns_wait(c->asyncns, 0) < 0)
391         goto fail;
392
393     if (!asyncns_isdone(c->asyncns, c->asyncns_query))
394         return;
395
396     ret = asyncns_getaddrinfo_done(c->asyncns, c->asyncns_query, &res);
397     c->asyncns_query = NULL;
398
399     if (ret != 0 || !res)
400         goto fail;
401
402     if (res->ai_addr)
403         sockaddr_prepare(c, res->ai_addr, res->ai_addrlen);
404
405     asyncns_freeaddrinfo(res);
406
407     m->io_free(c->asyncns_io_event);
408     c->asyncns_io_event = NULL;
409     return;
410
411 fail:
412     m->io_free(c->asyncns_io_event);
413     c->asyncns_io_event = NULL;
414
415     errno = EHOSTUNREACH;
416     do_call(c);
417     return;
418
419 }
420
421 #endif
422
423 static void timeout_cb(pa_mainloop_api *m, pa_time_event *e, const struct timeval *tv, void *userdata) {
424     pa_socket_client *c = userdata;
425
426     pa_assert(m);
427     pa_assert(e);
428     pa_assert(tv);
429     pa_assert(c);
430
431     if (c->fd >= 0) {
432         pa_close(c->fd);
433         c->fd = -1;
434     }
435
436     errno = ETIMEDOUT;
437     do_call(c);
438 }
439
440 static void start_timeout(pa_socket_client *c) {
441     struct timeval tv;
442     pa_assert(c);
443     pa_assert(!c->timeout_event);
444
445     pa_gettimeofday(&tv);
446     pa_timeval_add(&tv, CONNECT_TIMEOUT * PA_USEC_PER_SEC);
447     c->timeout_event = c->mainloop->time_new(c->mainloop, &tv, timeout_cb, c);
448 }
449
450 pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, 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);
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);
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);
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);
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 }