Merge "lock: Improve performance of DEBUG_THREADS."
[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 "asterisk.h"
20
21 #include "asterisk/iostream.h"          /* for DO_SSL */
22
23 #include <fcntl.h>                      /* for O_NONBLOCK */
24 #ifdef DO_SSL
25 #include <openssl/err.h>                /* for ERR_error_string */
26 #include <openssl/opensslv.h>           /* for OPENSSL_VERSION_NUMBER */
27 #include <openssl/ssl.h>                /* for SSL_get_error, SSL_free, SSL_... */
28 #endif
29 #include <sys/socket.h>                 /* for shutdown, SHUT_RDWR */
30 #include <sys/time.h>                   /* for timeval */
31
32 #include "asterisk/astobj2.h"           /* for ao2_alloc_options, ao2_alloc_... */
33 #include "asterisk/logger.h"            /* for ast_debug, ast_log, LOG_ERROR */
34 #include "asterisk/strings.h"           /* for asterisk/threadstorage.h */
35 #include "asterisk/threadstorage.h"     /* for ast_threadstorage_get, AST_TH... */
36 #include "asterisk/time.h"              /* for ast_remaining_ms, ast_tvnow */
37 #include "asterisk/utils.h"             /* for ast_wait_for_input, ast_wait_... */
38
39 struct ast_iostream {
40         SSL *ssl;
41         struct timeval start;
42         int fd;
43         int timeout;
44         int timeout_reset;
45         int exclusive_input;
46         int rbuflen;
47         char *rbufhead;
48         char rbuf[2048];
49 };
50
51 #if defined(DO_SSL)
52 AST_THREADSTORAGE(err2str_threadbuf);
53 #define ERR2STR_BUFSIZE   128
54
55 static const char *ssl_error_to_string(int sslerr, int ret)
56 {
57         switch (sslerr) {
58         case SSL_ERROR_SSL:
59                 return "Internal SSL error";
60         case SSL_ERROR_SYSCALL:
61                 if (!ret) {
62                         return "System call EOF";
63                 } else if (ret == -1) {
64                         char *buf;
65
66                         buf = ast_threadstorage_get(&err2str_threadbuf, ERR2STR_BUFSIZE);
67                         if (!buf) {
68                                 return "Unknown";
69                         }
70
71                         snprintf(buf, ERR2STR_BUFSIZE, "Underlying BIO error: %s", strerror(errno));
72                         return buf;
73                 } else {
74                         return "System call other";
75                 }
76         default:
77                 break;
78         }
79
80         return "Unknown";
81 }
82 #endif
83
84 int ast_iostream_get_fd(struct ast_iostream *stream)
85 {
86         return stream->fd;
87 }
88
89 void ast_iostream_nonblock(struct ast_iostream *stream)
90 {
91         ast_fd_set_flags(stream->fd, O_NONBLOCK);
92 }
93
94 SSL *ast_iostream_get_ssl(struct ast_iostream *stream)
95 {
96         return stream->ssl;
97 }
98
99 void ast_iostream_set_timeout_disable(struct ast_iostream *stream)
100 {
101         ast_assert(stream != NULL);
102
103         stream->timeout = -1;
104         stream->timeout_reset = -1;
105 }
106
107 void ast_iostream_set_timeout_inactivity(struct ast_iostream *stream, int timeout)
108 {
109         ast_assert(stream != NULL);
110
111         stream->start.tv_sec = 0;
112         stream->timeout = timeout;
113         stream->timeout_reset = timeout;
114 }
115
116 void ast_iostream_set_timeout_idle_inactivity(struct ast_iostream *stream, int timeout, int timeout_reset)
117 {
118         ast_assert(stream != NULL);
119
120         stream->start.tv_sec = 0;
121         stream->timeout = timeout;
122         stream->timeout_reset = timeout_reset;
123 }
124
125 void ast_iostream_set_timeout_sequence(struct ast_iostream *stream, struct timeval start, int timeout)
126 {
127         ast_assert(stream != NULL);
128
129         stream->start = start;
130         stream->timeout = timeout;
131         stream->timeout_reset = timeout;
132 }
133
134 void ast_iostream_set_exclusive_input(struct ast_iostream *stream, int exclusive_input)
135 {
136         ast_assert(stream != NULL);
137
138         stream->exclusive_input = exclusive_input;
139 }
140
141 static ssize_t iostream_read(struct ast_iostream *stream, void *buf, size_t size)
142 {
143         struct timeval start;
144         int ms;
145         int res;
146
147         if (stream->start.tv_sec) {
148                 start = stream->start;
149         } else {
150                 start = ast_tvnow();
151         }
152
153 #if defined(DO_SSL)
154         if (stream->ssl) {
155                 for (;;) {
156                         int sslerr;
157                         char err[256];
158                         res = SSL_read(stream->ssl, buf, size);
159                         if (0 < res) {
160                                 /* We read some payload data. */
161                                 stream->timeout = stream->timeout_reset;
162                                 return res;
163                         }
164                         sslerr = SSL_get_error(stream->ssl, res);
165                         switch (sslerr) {
166                         case SSL_ERROR_ZERO_RETURN:
167                                 /* Report EOF for a shutdown */
168                                 ast_debug(1, "TLS clean shutdown alert reading data\n");
169                                 return 0;
170                         case SSL_ERROR_WANT_READ:
171                                 if (!stream->exclusive_input) {
172                                         /* We cannot wait for data now. */
173                                         errno = EAGAIN;
174                                         return -1;
175                                 }
176                                 while ((ms = ast_remaining_ms(start, stream->timeout))) {
177                                         res = ast_wait_for_input(stream->fd, ms);
178                                         if (0 < res) {
179                                                 /* Socket is ready to be read. */
180                                                 break;
181                                         }
182                                         if (res < 0) {
183                                                 if (errno == EINTR || errno == EAGAIN) {
184                                                         /* Try again. */
185                                                         continue;
186                                                 }
187                                                 ast_debug(1, "TLS socket error waiting for read data: %s\n",
188                                                         strerror(errno));
189                                                 return -1;
190                                         }
191                                 }
192                                 break;
193                         case SSL_ERROR_WANT_WRITE:
194                                 while ((ms = ast_remaining_ms(start, stream->timeout))) {
195                                         res = ast_wait_for_output(stream->fd, ms);
196                                         if (0 < res) {
197                                                 /* Socket is ready to be written. */
198                                                 break;
199                                         }
200                                         if (res < 0) {
201                                                 if (errno == EINTR || errno == EAGAIN) {
202                                                         /* Try again. */
203                                                         continue;
204                                                 }
205                                                 ast_debug(1, "TLS socket error waiting for write space: %s\n",
206                                                         strerror(errno));
207                                                 return -1;
208                                         }
209                                 }
210                                 break;
211                         case SSL_ERROR_SYSCALL:
212                                 /* Some non-recoverable I/O error occurred. The OpenSSL error queue may
213                                  * contain more information on the error. For socket I/O on Unix systems,
214                                  * consult errno for details. */
215                                 ast_debug(1, "TLS non-recoverable I/O error occurred: %s, %s\n", ERR_error_string(sslerr, err),
216                                         ssl_error_to_string(sslerr, res));
217                                 return -1;
218                         default:
219                                 /* Report EOF for an undecoded SSL or transport error. */
220                                 ast_debug(1, "TLS transport or SSL error reading data:  %s, %s\n", ERR_error_string(sslerr, err),
221                                         ssl_error_to_string(sslerr, res));
222                                 return -1;
223                         }
224                         if (!ms) {
225                                 /* Report EOF for a timeout */
226                                 ast_debug(1, "TLS timeout reading data\n");
227                                 return 0;
228                         }
229                 }
230         }
231 #endif  /* defined(DO_SSL) */
232
233         for (;;) {
234                 res = read(stream->fd, buf, size);
235                 if (0 <= res) {
236                         /* Got data or we cannot wait for it. */
237                         stream->timeout = stream->timeout_reset;
238                         return res;
239                 }
240                 if (!stream->exclusive_input) {
241                         return res;
242                 }
243                 if (errno != EINTR && errno != EAGAIN) {
244                         /* Not a retryable error. */
245                         ast_debug(1, "TCP socket error reading data: %s\n",
246                                 strerror(errno));
247                         return -1;
248                 }
249                 ms = ast_remaining_ms(start, stream->timeout);
250                 if (!ms) {
251                         /* Report EOF for a timeout */
252                         ast_debug(1, "TCP timeout reading data\n");
253                         return 0;
254                 }
255                 ast_wait_for_input(stream->fd, ms);
256         }
257 }
258
259 ssize_t ast_iostream_read(struct ast_iostream *stream, void *buffer, size_t count)
260 {
261         if (!count) {
262                 /* You asked for no data you got no data. */
263                 return 0;
264         }
265
266         if (!stream || stream->fd == -1) {
267                 errno = EBADF;
268                 return -1;
269         }
270
271         /* Get any remains from the read buffer */
272         if (stream->rbuflen) {
273                 size_t r = count;
274                 if (r > stream->rbuflen) {
275                         r = stream->rbuflen;
276                 }
277                 memcpy(buffer, stream->rbufhead, r);
278                 stream->rbuflen -= r;
279                 stream->rbufhead += r;
280                 return r;
281         }
282
283         return iostream_read(stream, buffer, count);
284 }
285
286 ssize_t ast_iostream_gets(struct ast_iostream *stream, char *buffer, size_t size)
287 {
288         size_t remaining = size;
289         ssize_t accum_size = 0;
290         ssize_t len;
291         char *newline;
292
293         for (;;) {
294                 /* Search for newline */
295                 newline = memchr(stream->rbufhead, '\n', stream->rbuflen);
296                 if (newline) {
297                         len = newline - stream->rbufhead + 1;
298                         if (len > remaining - 1) {
299                                 len = remaining - 1;
300                         }
301                         break;
302                 }
303
304                 /* Enough buffered line data to fill request buffer? */
305                 if (stream->rbuflen >= remaining - 1) {
306                         len = remaining - 1;
307                         break;
308                 }
309                 if (stream->rbuflen) {
310                         /* Put leftover buffered line data into request buffer */
311                         memcpy(buffer + accum_size, stream->rbufhead, stream->rbuflen);
312                         remaining -= stream->rbuflen;
313                         accum_size += stream->rbuflen;
314                         stream->rbuflen = 0;
315                 }
316                 stream->rbufhead = stream->rbuf;
317
318                 len = iostream_read(stream, stream->rbuf, sizeof(stream->rbuf));
319                 if (len == 0) {
320                         /* Nothing new was read.  Return whatever we have accumulated. */
321                         break;
322                 }
323                 if (len < 0) {
324                         if (accum_size) {
325                                 /* We have an accumulated buffer so return that instead. */
326                                 len = 0;
327                                 break;
328                         }
329                         return len;
330                 }
331                 stream->rbuflen += len;
332         }
333
334         /* Return read buffer string length */
335         memcpy(buffer + accum_size, stream->rbufhead, len);
336         buffer[accum_size + len] = 0;
337         stream->rbuflen -= len;
338         stream->rbufhead += len;
339
340         return accum_size + len;
341 }
342
343 ssize_t ast_iostream_discard(struct ast_iostream *stream, size_t size)
344 {
345         char buf[1024];
346         size_t remaining = size;
347         ssize_t ret;
348
349         while (remaining) {
350                 ret = ast_iostream_read(stream, buf, remaining > sizeof(buf) ? sizeof(buf) : remaining);
351                 if (ret <= 0) {
352                         return ret;
353                 }
354                 remaining -= ret;
355         }
356
357         return size;
358 }
359
360 ssize_t ast_iostream_write(struct ast_iostream *stream, const void *buffer, size_t size)
361 {
362         struct timeval start;
363         int ms;
364         int res;
365         int written;
366         int remaining;
367
368         if (!size) {
369                 /* You asked to write no data you wrote no data. */
370                 return 0;
371         }
372
373         if (!stream || stream->fd == -1) {
374                 errno = EBADF;
375                 return -1;
376         }
377
378         if (stream->start.tv_sec) {
379                 start = stream->start;
380         } else {
381                 start = ast_tvnow();
382         }
383
384 #if defined(DO_SSL)
385         if (stream->ssl) {
386                 written = 0;
387                 remaining = size;
388                 for (;;) {
389                         int sslerr;
390                         char err[256];
391                         res = SSL_write(stream->ssl, buffer + written, remaining);
392                         if (res == remaining) {
393                                 /* Everything was written. */
394                                 return size;
395                         }
396                         if (0 < res) {
397                                 /* Successfully wrote part of the buffer.  Try to write the rest. */
398                                 written += res;
399                                 remaining -= res;
400                                 continue;
401                         }
402                         sslerr = SSL_get_error(stream->ssl, res);
403                         switch (sslerr) {
404                         case SSL_ERROR_ZERO_RETURN:
405                                 ast_debug(1, "TLS clean shutdown alert writing data\n");
406                                 if (written) {
407                                         /* Report partial write. */
408                                         return written;
409                                 }
410                                 errno = EBADF;
411                                 return -1;
412                         case SSL_ERROR_WANT_READ:
413                                 ms = ast_remaining_ms(start, stream->timeout);
414                                 if (!ms) {
415                                         /* Report partial write. */
416                                         ast_debug(1, "TLS timeout writing data (want read)\n");
417                                         return written;
418                                 }
419                                 ast_wait_for_input(stream->fd, ms);
420                                 break;
421                         case SSL_ERROR_WANT_WRITE:
422                                 ms = ast_remaining_ms(start, stream->timeout);
423                                 if (!ms) {
424                                         /* Report partial write. */
425                                         ast_debug(1, "TLS timeout writing data (want write)\n");
426                                         return written;
427                                 }
428                                 ast_wait_for_output(stream->fd, ms);
429                                 break;
430                         default:
431                                 /* Undecoded SSL or transport error. */
432                                 ast_debug(1, "TLS transport or SSL error writing data: %s, %s\n", ERR_error_string(sslerr, err),
433                                         ssl_error_to_string(sslerr, res));
434                                 if (written) {
435                                         /* Report partial write. */
436                                         return written;
437                                 }
438                                 errno = EBADF;
439                                 return -1;
440                         }
441                 }
442         }
443 #endif  /* defined(DO_SSL) */
444
445         written = 0;
446         remaining = size;
447         for (;;) {
448                 res = write(stream->fd, buffer + written, remaining);
449                 if (res == remaining) {
450                         /* Yay everything was written. */
451                         return size;
452                 }
453                 if (0 < res) {
454                         /* Successfully wrote part of the buffer.  Try to write the rest. */
455                         written += res;
456                         remaining -= res;
457                         continue;
458                 }
459                 if (errno != EINTR && errno != EAGAIN) {
460                         /* Not a retryable error. */
461                         ast_debug(1, "TCP socket error writing: %s\n", strerror(errno));
462                         if (written) {
463                                 return written;
464                         }
465                         return -1;
466                 }
467                 ms = ast_remaining_ms(start, stream->timeout);
468                 if (!ms) {
469                         /* Report partial write. */
470                         ast_debug(1, "TCP timeout writing data\n");
471                         return written;
472                 }
473                 ast_wait_for_output(stream->fd, ms);
474         }
475 }
476
477 ssize_t ast_iostream_printf(struct ast_iostream *stream, const char *format, ...)
478 {
479         char sbuf[512], *buf = sbuf;
480         int len, len2, ret = -1;
481         va_list va;
482
483         va_start(va, format);
484         len = vsnprintf(buf, sizeof(sbuf), format, va);
485         va_end(va);
486
487         if (len > sizeof(sbuf) - 1) {
488                 /* Add one to the string length to accommodate the NULL byte */
489                 size_t buf_len = len + 1;
490
491                 buf = ast_malloc(buf_len);
492                 if (!buf) {
493                         return -1;
494                 }
495                 va_start(va, format);
496                 len2 = vsnprintf(buf, buf_len, format, va);
497                 va_end(va);
498                 if (len2 != len) {
499                         goto error;
500                 }
501         }
502
503         if (ast_iostream_write(stream, buf, len) == len)
504                 ret = len;
505
506 error:
507         if (buf != sbuf) {
508                 ast_free(buf);
509         }
510
511         return ret;
512 }
513
514 int ast_iostream_close(struct ast_iostream *stream)
515 {
516         if (!stream) {
517                 errno = EBADF;
518                 return -1;
519         }
520
521         if (stream->fd != -1) {
522 #if defined(DO_SSL)
523                 if (stream->ssl) {
524                         int res;
525
526                         /*
527                          * According to the TLS standard, it is acceptable for an
528                          * application to only send its shutdown alert and then
529                          * close the underlying connection without waiting for
530                          * the peer's response (this way resources can be saved,
531                          * as the process can already terminate or serve another
532                          * connection).
533                          */
534                         res = SSL_shutdown(stream->ssl);
535                         if (res < 0) {
536                                 int sslerr = SSL_get_error(stream->ssl, res);
537                                 char err[256];
538                                 ast_log(LOG_ERROR, "SSL_shutdown() failed: %s, %s\n",
539                                         ERR_error_string(sslerr, err), ssl_error_to_string(sslerr, res));
540                         }
541
542 #if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x10100000L)
543                         if (!SSL_is_server(stream->ssl)) {
544 #else
545                         if (!stream->ssl->server) {
546 #endif
547                                 /* For client threads, ensure that the error stack is cleared */
548 #if defined(LIBRESSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x10100000L)
549 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
550                                 ERR_remove_thread_state(NULL);
551 #else
552                                 ERR_remove_state(0);
553 #endif  /* OPENSSL_VERSION_NUMBER >= 0x10000000L */
554 #endif  /* OPENSSL_VERSION_NUMBER  < 0x10100000L */
555                         }
556
557                         SSL_free(stream->ssl);
558                         stream->ssl = NULL;
559                 }
560 #endif  /* defined(DO_SSL) */
561
562                 /*
563                  * Issuing shutdown() is necessary here to avoid a race
564                  * condition where the last data written may not appear
565                  * in the TCP stream.  See ASTERISK-23548
566                  */
567                 shutdown(stream->fd, SHUT_RDWR);
568                 if (close(stream->fd)) {
569                         ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
570                 }
571                 stream->fd = -1;
572         }
573         ao2_t_ref(stream, -1, "Closed ast_iostream");
574
575         return 0;
576 }
577
578 static void iostream_dtor(void *cookie)
579 {
580 #ifdef AST_DEVMODE
581         /* Since the ast_assert below is the only one using stream,
582          * and ast_assert is only available with AST_DEVMODE, we
583          * put this in a conditional to avoid compiler warnings. */
584         struct ast_iostream *stream = cookie;
585 #endif
586
587         ast_assert(stream->fd == -1);
588 }
589
590 struct ast_iostream *ast_iostream_from_fd(int *fd)
591 {
592         struct ast_iostream *stream;
593
594         stream = ao2_alloc_options(sizeof(*stream), iostream_dtor,
595                 AO2_ALLOC_OPT_LOCK_NOLOCK);
596         if (stream) {
597                 stream->timeout = -1;
598                 stream->timeout_reset = -1;
599                 stream->fd = *fd;
600                 *fd = -1;
601         }
602
603         return stream;
604 }
605
606 int ast_iostream_start_tls(struct ast_iostream **pstream, SSL_CTX *ssl_ctx, int client)
607 {
608 #ifdef DO_SSL
609         struct ast_iostream *stream = *pstream;
610         int (*ssl_setup)(SSL *) = client ? SSL_connect : SSL_accept;
611         int res;
612
613         stream->ssl = SSL_new(ssl_ctx);
614         if (!stream->ssl) {
615                 ast_log(LOG_ERROR, "Unable to create new SSL connection\n");
616                 errno = ENOMEM;
617                 return -1;
618         }
619
620         /*
621          * This function takes struct ast_iostream **, so it can chain
622          * SSL over any ast_iostream. For now we assume it's a file descriptor.
623          * But later this should instead use BIO wrapper to tie SSL to another
624          * ast_iostream.
625          */
626         SSL_set_fd(stream->ssl, stream->fd);
627
628         res = ssl_setup(stream->ssl);
629         if (res <= 0) {
630                 int sslerr = SSL_get_error(stream->ssl, res);
631                 char err[256];
632
633                 ast_log(LOG_ERROR, "Problem setting up ssl connection: %s, %s\n",
634                         ERR_error_string(sslerr, err), ssl_error_to_string(sslerr, res));
635                 errno = EIO;
636                 return -1;
637         }
638
639         return 0;
640 #else
641         ast_log(LOG_ERROR, "SSL not enabled in this build\n");
642         errno = ENOTSUP;
643         return -1;
644 #endif
645 }