46abc18a5c88935d34cbd7533201e456e6a7ed10
[asterisk/asterisk.git] / main / iostream.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2015, Digium, Inc.
5  *
6  * Timo Teräs <timo.teras@iki.fi>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 #include <fcntl.h>
20 #include <stdarg.h>
21
22 #include "asterisk.h"
23 #include "asterisk/utils.h"
24 #include "asterisk/astobj2.h"
25 #include "asterisk/iostream.h"
26
27 struct ast_iostream {
28         SSL *ssl;
29         struct timeval start;
30         int fd;
31         int timeout;
32         int timeout_reset;
33         int exclusive_input;
34         int rbuflen;
35         char *rbufhead;
36         char rbuf[2048];
37 };
38
39 int ast_iostream_get_fd(struct ast_iostream *stream)
40 {
41         return stream->fd;
42 }
43
44 void ast_iostream_nonblock(struct ast_iostream *stream)
45 {
46         fcntl(stream->fd, F_SETFL, fcntl(stream->fd, F_GETFL) | O_NONBLOCK);
47 }
48
49 SSL *ast_iostream_get_ssl(struct ast_iostream *stream)
50 {
51         return stream->ssl;
52 }
53
54 void ast_iostream_set_timeout_disable(struct ast_iostream *stream)
55 {
56         ast_assert(stream != NULL);
57
58         stream->timeout = -1;
59         stream->timeout_reset = -1;
60 }
61
62 void ast_iostream_set_timeout_inactivity(struct ast_iostream *stream, int timeout)
63 {
64         ast_assert(stream != NULL);
65
66         stream->start.tv_sec = 0;
67         stream->timeout = timeout;
68         stream->timeout_reset = timeout;
69 }
70
71 void ast_iostream_set_timeout_idle_inactivity(struct ast_iostream *stream, int timeout, int timeout_reset)
72 {
73         ast_assert(stream != NULL);
74
75         stream->start.tv_sec = 0;
76         stream->timeout = timeout;
77         stream->timeout_reset = timeout_reset;
78 }
79
80 void ast_iostream_set_timeout_sequence(struct ast_iostream *stream, struct timeval start, int timeout)
81 {
82         ast_assert(stream != NULL);
83
84         stream->start = start;
85         stream->timeout = timeout;
86         stream->timeout_reset = timeout;
87 }
88
89 void ast_iostream_set_exclusive_input(struct ast_iostream *stream, int exclusive_input)
90 {
91         ast_assert(stream != NULL);
92
93         stream->exclusive_input = exclusive_input;
94 }
95
96 static ssize_t iostream_read(struct ast_iostream *stream, void *buf, size_t size)
97 {
98         struct timeval start;
99         int ms;
100         int res;
101
102         if (stream->start.tv_sec) {
103                 start = stream->start;
104         } else {
105                 start = ast_tvnow();
106         }
107
108 #if defined(DO_SSL)
109         if (stream->ssl) {
110                 for (;;) {
111                         res = SSL_read(stream->ssl, buf, size);
112                         if (0 < res) {
113                                 /* We read some payload data. */
114                                 stream->timeout = stream->timeout_reset;
115                                 return res;
116                         }
117                         switch (SSL_get_error(stream->ssl, res)) {
118                         case SSL_ERROR_ZERO_RETURN:
119                                 /* Report EOF for a shutdown */
120                                 ast_debug(1, "TLS clean shutdown alert reading data\n");
121                                 return 0;
122                         case SSL_ERROR_WANT_READ:
123                                 if (!stream->exclusive_input) {
124                                         /* We cannot wait for data now. */
125                                         errno = EAGAIN;
126                                         return -1;
127                                 }
128                                 while ((ms = ast_remaining_ms(start, stream->timeout))) {
129                                         res = ast_wait_for_input(stream->fd, ms);
130                                         if (0 < res) {
131                                                 /* Socket is ready to be read. */
132                                                 break;
133                                         }
134                                         if (res < 0) {
135                                                 if (errno == EINTR || errno == EAGAIN) {
136                                                         /* Try again. */
137                                                         continue;
138                                                 }
139                                                 ast_debug(1, "TLS socket error waiting for read data: %s\n",
140                                                         strerror(errno));
141                                                 return -1;
142                                         }
143                                 }
144                                 break;
145                         case SSL_ERROR_WANT_WRITE:
146                                 while ((ms = ast_remaining_ms(start, stream->timeout))) {
147                                         res = ast_wait_for_output(stream->fd, ms);
148                                         if (0 < res) {
149                                                 /* Socket is ready to be written. */
150                                                 break;
151                                         }
152                                         if (res < 0) {
153                                                 if (errno == EINTR || errno == EAGAIN) {
154                                                         /* Try again. */
155                                                         continue;
156                                                 }
157                                                 ast_debug(1, "TLS socket error waiting for write space: %s\n",
158                                                         strerror(errno));
159                                                 return -1;
160                                         }
161                                 }
162                                 break;
163                         default:
164                                 /* Report EOF for an undecoded SSL or transport error. */
165                                 ast_debug(1, "TLS transport or SSL error reading data\n");
166                                 return 0;
167                         }
168                         if (!ms) {
169                                 /* Report EOF for a timeout */
170                                 ast_debug(1, "TLS timeout reading data\n");
171                                 return 0;
172                         }
173                 }
174         }
175 #endif  /* defined(DO_SSL) */
176
177         for (;;) {
178                 res = read(stream->fd, buf, size);
179                 if (0 <= res) {
180                         /* Got data or we cannot wait for it. */
181                         stream->timeout = stream->timeout_reset;
182                         return res;
183                 }
184                 if (!stream->exclusive_input) {
185                         return res;
186                 }
187                 if (errno != EINTR && errno != EAGAIN) {
188                         /* Not a retryable error. */
189                         ast_debug(1, "TCP socket error reading data: %s\n",
190                                 strerror(errno));
191                         return -1;
192                 }
193                 ms = ast_remaining_ms(start, stream->timeout);
194                 if (!ms) {
195                         /* Report EOF for a timeout */
196                         ast_debug(1, "TCP timeout reading data\n");
197                         return 0;
198                 }
199                 ast_wait_for_input(stream->fd, ms);
200         }
201 }
202
203 ssize_t ast_iostream_read(struct ast_iostream *stream, void *buf, size_t size)
204 {
205         if (!size) {
206                 /* You asked for no data you got no data. */
207                 return 0;
208         }
209
210         if (!stream || stream->fd == -1) {
211                 errno = EBADF;
212                 return -1;
213         }
214
215         /* Get any remains from the read buffer */
216         if (stream->rbuflen) {
217                 size_t r = size;
218                 if (r > stream->rbuflen) {
219                         r = stream->rbuflen;
220                 }
221                 memcpy(buf, stream->rbufhead, r);
222                 stream->rbuflen -= r;
223                 stream->rbufhead += r;
224                 return r;
225         }
226
227         return iostream_read(stream, buf, size);
228 }
229
230 ssize_t ast_iostream_gets(struct ast_iostream *stream, char *buf, size_t count)
231 {
232         ssize_t r;
233         char *newline;
234
235         do {
236                 /* Search for newline */
237                 newline = memchr(stream->rbufhead, '\n', stream->rbuflen);
238                 if (newline) {
239                         r = newline - stream->rbufhead + 1;
240                         if (r > count-1) {
241                                 r = count-1;
242                         }
243                         break;
244                 }
245
246                 /* Enough data? */
247                 if (stream->rbuflen >= count - 1) {
248                         r = count - 1;
249                         break;
250                 }
251
252                 /* Try to fill in line buffer */
253                 if (stream->rbuflen && stream->rbuf != stream->rbufhead) {
254                         memmove(&stream->rbuf, stream->rbufhead, stream->rbuflen);
255                 }
256                 stream->rbufhead = stream->rbuf;
257
258                 r = iostream_read(stream, stream->rbufhead + stream->rbuflen, sizeof(stream->rbuf) - stream->rbuflen);
259                 if (r <= 0) {
260                         return r;
261                 }
262                 stream->rbuflen += r;
263         } while (1);
264
265         /* Return r bytes with termination byte */
266         memcpy(buf, stream->rbufhead, r);
267         buf[r] = 0;
268         stream->rbuflen -= r;
269         stream->rbufhead += r;
270
271         return r;
272 }
273
274 ssize_t ast_iostream_discard(struct ast_iostream *stream, size_t size)
275 {
276         char buf[1024];
277         size_t remaining = size;
278         ssize_t ret;
279
280         while (remaining) {
281                 ret = ast_iostream_read(stream, buf, remaining > sizeof(buf) ? sizeof(buf) : remaining);
282                 if (ret < 0) {
283                         return ret;
284                 }
285                 remaining -= ret;
286         }
287
288         return size;
289 }
290
291 ssize_t ast_iostream_write(struct ast_iostream *stream, const void *buf, size_t size)
292 {
293         struct timeval start;
294         int ms;
295         int res;
296         int written;
297         int remaining;
298
299         if (!size) {
300                 /* You asked to write no data you wrote no data. */
301                 return 0;
302         }
303
304         if (!stream || stream->fd == -1) {
305                 errno = EBADF;
306                 return -1;
307         }
308
309         if (stream->start.tv_sec) {
310                 start = stream->start;
311         } else {
312                 start = ast_tvnow();
313         }
314
315 #if defined(DO_SSL)
316         if (stream->ssl) {
317                 written = 0;
318                 remaining = size;
319                 for (;;) {
320                         res = SSL_write(stream->ssl, buf + written, remaining);
321                         if (res == remaining) {
322                                 /* Everything was written. */
323                                 return size;
324                         }
325                         if (0 < res) {
326                                 /* Successfully wrote part of the buffer.  Try to write the rest. */
327                                 written += res;
328                                 remaining -= res;
329                                 continue;
330                         }
331                         switch (SSL_get_error(stream->ssl, res)) {
332                         case SSL_ERROR_ZERO_RETURN:
333                                 ast_debug(1, "TLS clean shutdown alert writing data\n");
334                                 if (written) {
335                                         /* Report partial write. */
336                                         return written;
337                                 }
338                                 errno = EBADF;
339                                 return -1;
340                         case SSL_ERROR_WANT_READ:
341                                 ms = ast_remaining_ms(start, stream->timeout);
342                                 if (!ms) {
343                                         /* Report partial write. */
344                                         ast_debug(1, "TLS timeout writing data (want read)\n");
345                                         return written;
346                                 }
347                                 ast_wait_for_input(stream->fd, ms);
348                                 break;
349                         case SSL_ERROR_WANT_WRITE:
350                                 ms = ast_remaining_ms(start, stream->timeout);
351                                 if (!ms) {
352                                         /* Report partial write. */
353                                         ast_debug(1, "TLS timeout writing data (want write)\n");
354                                         return written;
355                                 }
356                                 ast_wait_for_output(stream->fd, ms);
357                                 break;
358                         default:
359                                 /* Undecoded SSL or transport error. */
360                                 ast_debug(1, "TLS transport or SSL error writing data\n");
361                                 if (written) {
362                                         /* Report partial write. */
363                                         return written;
364                                 }
365                                 errno = EBADF;
366                                 return -1;
367                         }
368                 }
369         }
370 #endif  /* defined(DO_SSL) */
371
372         written = 0;
373         remaining = size;
374         for (;;) {
375                 res = write(stream->fd, buf + written, remaining);
376                 if (res == remaining) {
377                         /* Yay everything was written. */
378                         return size;
379                 }
380                 if (0 < res) {
381                         /* Successfully wrote part of the buffer.  Try to write the rest. */
382                         written += res;
383                         remaining -= res;
384                         continue;
385                 }
386                 if (errno != EINTR && errno != EAGAIN) {
387                         /* Not a retryable error. */
388                         ast_debug(1, "TCP socket error writing: %s\n", strerror(errno));
389                         if (written) {
390                                 return written;
391                         }
392                         return -1;
393                 }
394                 ms = ast_remaining_ms(start, stream->timeout);
395                 if (!ms) {
396                         /* Report partial write. */
397                         ast_debug(1, "TCP timeout writing data\n");
398                         return written;
399                 }
400                 ast_wait_for_output(stream->fd, ms);
401         }
402 }
403
404 ssize_t ast_iostream_printf(struct ast_iostream *stream, const void *fmt, ...)
405 {
406         char sbuf[256], *buf = sbuf;
407         int len, len2, ret = -1;
408         va_list va;
409
410         va_start(va, fmt);
411         len = vsnprintf(buf, sizeof(sbuf), fmt, va);
412         va_end(va);
413
414         if (len > sizeof(sbuf)) {
415                 buf = ast_malloc(len);
416                 if (!buf) {
417                         return -1;
418                 }
419                 va_start(va, fmt);
420                 len2 = vsnprintf(buf, len, fmt, va);
421                 va_end(va);
422                 if (len2 > len) {
423                         goto error;
424                 }
425         }
426
427         if (ast_iostream_write(stream, buf, len) == len)
428                 ret = len;
429
430 error:
431         if (buf != sbuf) {
432                 ast_free(buf);
433         }
434
435         return ret;
436 }
437
438 int ast_iostream_close(struct ast_iostream *stream)
439 {
440         if (!stream) {
441                 errno = EBADF;
442                 return -1;
443         }
444
445         if (stream->fd != -1) {
446 #if defined(DO_SSL)
447                 if (stream->ssl) {
448                         int res;
449
450                         /*
451                          * According to the TLS standard, it is acceptable for an
452                          * application to only send its shutdown alert and then
453                          * close the underlying connection without waiting for
454                          * the peer's response (this way resources can be saved,
455                          * as the process can already terminate or serve another
456                          * connection).
457                          */
458                         res = SSL_shutdown(stream->ssl);
459                         if (res < 0) {
460                                 ast_log(LOG_ERROR, "SSL_shutdown() failed: %d\n",
461                                         SSL_get_error(stream->ssl, res));
462                         }
463
464                         if (!stream->ssl->server) {
465                                 /* For client threads, ensure that the error stack is cleared */
466                                 ERR_remove_state(0);
467                         }
468
469                         SSL_free(stream->ssl);
470                         stream->ssl = NULL;
471                 }
472 #endif  /* defined(DO_SSL) */
473
474                 /*
475                  * Issuing shutdown() is necessary here to avoid a race
476                  * condition where the last data written may not appear
477                  * in the TCP stream.  See ASTERISK-23548
478                  */
479                 shutdown(stream->fd, SHUT_RDWR);
480                 if (close(stream->fd)) {
481                         ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
482                 }
483                 stream->fd = -1;
484         }
485         ao2_t_ref(stream, -1, "Closed ast_iostream");
486
487         return 0;
488 }
489
490 static void iostream_dtor(void *cookie)
491 {
492 #ifdef AST_DEVMODE
493         /* Since the ast_assert below is the only one using stream,
494          * and ast_assert is only available with AST_DEVMODE, we
495          * put this in a conditional to avoid compiler warnings. */
496         struct ast_iostream *stream = cookie;
497 #endif
498
499         ast_assert(stream->fd == -1);
500 }
501
502 struct ast_iostream *ast_iostream_from_fd(int *fd)
503 {
504         struct ast_iostream *stream;
505
506         stream = ao2_alloc_options(sizeof(*stream), iostream_dtor,
507                 AO2_ALLOC_OPT_LOCK_NOLOCK);
508         if (stream) {
509                 stream->timeout = -1;
510                 stream->timeout_reset = -1;
511                 stream->fd = *fd;
512                 *fd = -1;
513         }
514
515         return stream;
516 }
517
518 int ast_iostream_start_tls(struct ast_iostream **pstream, SSL_CTX *ssl_ctx, int client)
519 {
520 #ifdef DO_SSL
521         struct ast_iostream *stream = *pstream;
522         int (*ssl_setup)(SSL *) = client ? SSL_connect : SSL_accept;
523         char err[256];
524
525         stream->ssl = SSL_new(ssl_ctx);
526         if (!stream->ssl) {
527                 ast_log(LOG_ERROR, "Unable to create new SSL connection\n");
528                 errno = ENOMEM;
529                 return -1;
530         }
531
532         /*
533          * This function takes struct ast_iostream **, so it can chain
534          * SSL over any ast_iostream. For now we assume it's a file descriptor.
535          * But later this should instead use BIO wrapper to tie SSL to another
536          * ast_iostream.
537          */
538         SSL_set_fd(stream->ssl, stream->fd);
539
540         if (ssl_setup(stream->ssl) <= 0) {
541                 ast_log(LOG_ERROR, "Problem setting up ssl connection: %s\n",
542                         ERR_error_string(ERR_get_error(), err));
543                 errno = EIO;
544                 return -1;
545         }
546
547         return 0;
548 #else
549         ast_log(LOG_ERROR, "SSL not enabled in this build\n");
550         errno = ENOTSUP;
551         return -1;
552 #endif
553 }