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