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