25#include <openssl/err.h>
26#include <openssl/opensslv.h>
27#include <openssl/ssl.h>
29#include <sys/socket.h>
54#define ERR2STR_BUFSIZE 128
56static const char *ssl_error_to_string(
int sslerr,
int ret)
60 return "Internal SSL error";
61 case SSL_ERROR_SYSCALL:
63 return "System call EOF";
64 }
else if (ret == -1) {
72 snprintf(
buf, ERR2STR_BUFSIZE,
"Underlying BIO error: %s", strerror(
errno));
75 return "System call other";
97 if (stream->
ssl && SSL_pending(stream->
ssl)) {
126 stream->
start.tv_sec = 0;
135 stream->
start.tv_sec = 0;
144 stream->
start = start;
168 struct timeval start;
172 if (stream->
start.tv_sec) {
173 start = stream->
start;
183 res = SSL_read(stream->
ssl,
buf, size);
189 sslerr = SSL_get_error(stream->
ssl, res);
191 case SSL_ERROR_ZERO_RETURN:
193 ast_debug(1,
"TLS clean shutdown alert reading data\n");
195 case SSL_ERROR_WANT_READ:
212 ast_debug(1,
"TLS socket error waiting for read data: %s\n",
218 case SSL_ERROR_WANT_WRITE:
230 ast_debug(1,
"TLS socket error waiting for write space: %s\n",
236 case SSL_ERROR_SYSCALL:
240 ast_debug(1,
"TLS non-recoverable I/O error occurred: %s, %s\n", ERR_error_string(sslerr, err),
241 ssl_error_to_string(sslerr, res));
245 ast_debug(1,
"TLS transport or SSL error reading data: %s, %s\n", ERR_error_string(sslerr, err),
246 ssl_error_to_string(sslerr, res));
251 ast_debug(1,
"TLS timeout reading data\n");
259 res = read(stream->
fd,
buf, size);
270 ast_debug(1,
"TCP socket error reading data: %s\n",
277 ast_debug(1,
"TCP timeout reading data\n");
291 if (!stream || stream->
fd == -1) {
302 memcpy(buffer, stream->
rbufhead, r);
313 size_t remaining = size;
314 ssize_t accum_size = 0;
323 if (
len > remaining - 1) {
330 if (stream->
rbuflen >= remaining - 1) {
360 memcpy(buffer + accum_size, stream->
rbufhead,
len);
361 buffer[accum_size +
len] = 0;
365 return accum_size +
len;
371 size_t remaining = size;
387 struct timeval start;
398 if (!stream || stream->
fd == -1) {
403 if (stream->
start.tv_sec) {
404 start = stream->
start;
416 res = SSL_write(stream->
ssl, buffer + written, remaining);
417 if (res == remaining) {
427 sslerr = SSL_get_error(stream->
ssl, res);
429 case SSL_ERROR_ZERO_RETURN:
430 ast_debug(1,
"TLS clean shutdown alert writing data\n");
437 case SSL_ERROR_WANT_READ:
441 ast_debug(1,
"TLS timeout writing data (want read)\n");
446 case SSL_ERROR_WANT_WRITE:
450 ast_debug(1,
"TLS timeout writing data (want write)\n");
457 ast_debug(1,
"TLS transport or SSL error writing data: %s, %s\n", ERR_error_string(sslerr, err),
458 ssl_error_to_string(sslerr, res));
473 res = write(stream->
fd, buffer + written, remaining);
474 if (res == remaining) {
495 ast_debug(1,
"TCP timeout writing data\n");
504 char sbuf[512], *
buf = sbuf;
505 int len, len2, ret = -1;
508 va_start(va, format);
509 len = vsnprintf(
buf,
sizeof(sbuf), format, va);
512 if (
len >
sizeof(sbuf) - 1) {
514 size_t buf_len =
len + 1;
520 va_start(va, format);
521 len2 = vsnprintf(
buf, buf_len, format, va);
546 if (stream->
fd != -1) {
559 res = SSL_shutdown(stream->
ssl);
561 int sslerr = SSL_get_error(stream->
ssl, res);
564 ERR_error_string(sslerr, err), ssl_error_to_string(sslerr, res));
567#if !(defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER < 0x2070000L)) && (OPENSSL_VERSION_NUMBER >= 0x10100000L)
568 if (!SSL_is_server(stream->
ssl)) {
570 if (!stream->
ssl->server) {
573#if defined(LIBRESSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x10100000L)
574#if OPENSSL_VERSION_NUMBER >= 0x10000000L
575 ERR_remove_thread_state(
NULL);
582 SSL_free(stream->
ssl);
592 shutdown(stream->
fd, SHUT_RDWR);
593 if (close(stream->
fd)) {
598 ao2_t_ref(stream, -1,
"Closed ast_iostream");
631 int (*ssl_setup)(
SSL *) = client ? SSL_connect : SSL_accept;
634 stream->
ssl = SSL_new(ssl_ctx);
647 SSL_set_fd(stream->
ssl, stream->
fd);
658 res = ssl_setup(stream->
ssl);
660 int sslerr = SSL_get_error(stream->
ssl, res);
664 ERR_error_string(sslerr, err), ssl_error_to_string(sslerr, res));
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdup(str)
A wrapper for strdup()
#define ast_malloc(len)
A wrapper for malloc()
#define ao2_t_ref(o, delta, tag)
@ AO2_ALLOC_OPT_LOCK_NOLOCK
#define ao2_alloc_options(data_size, destructor_fn, options)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Support for logging to various files, console and syslog Configuration in file logger....
#define ast_debug(level,...)
Log a DEBUG message.
ssize_t ast_iostream_printf(struct ast_iostream *stream, const char *format,...)
Write a formatted string to an iostream.
ssize_t ast_iostream_gets(struct ast_iostream *stream, char *buffer, size_t size)
Read a LF-terminated string from an iostream.
ssize_t ast_iostream_discard(struct ast_iostream *stream, size_t size)
Discard the specified number of bytes from an iostream.
ssize_t ast_iostream_write(struct ast_iostream *stream, const void *buffer, size_t size)
Write data to an iostream.
void ast_iostream_set_timeout_inactivity(struct ast_iostream *stream, int timeout)
Set the iostream inactivity timeout timer.
struct ast_iostream * ast_iostream_from_fd(int *fd)
Create an iostream from a file descriptor.
void ast_iostream_set_timeout_idle_inactivity(struct ast_iostream *stream, int timeout, int timeout_reset)
Set the iostream inactivity & idle timeout timers.
SSL * ast_iostream_get_ssl(struct ast_iostream *stream)
Get a pointer to an iostream's OpenSSL SSL structure.
int ast_iostream_get_fd(struct ast_iostream *stream)
Get an iostream's file descriptor.
int ast_iostream_start_tls(struct ast_iostream **pstream, SSL_CTX *ssl_ctx, int client)
Begin TLS on an iostream.
void ast_iostream_set_exclusive_input(struct ast_iostream *stream, int exclusive_input)
Set the iostream if it can exclusively depend upon the set timeouts.
int ast_iostream_set_sni_hostname(struct ast_iostream *stream, const char *sni_hostname)
Set the iostream's SNI hostname for TLS client connections.
ssize_t ast_iostream_read(struct ast_iostream *stream, void *buffer, size_t count)
Read data from an iostream.
static ssize_t iostream_read(struct ast_iostream *stream, void *buf, size_t size)
void ast_iostream_set_timeout_sequence(struct ast_iostream *stream, struct timeval start, int timeout)
Set the iostream I/O sequence timeout timer.
void ast_iostream_nonblock(struct ast_iostream *stream)
Make an iostream non-blocking.
int ast_iostream_close(struct ast_iostream *stream)
Close an iostream.
void ast_iostream_set_timeout_disable(struct ast_iostream *stream)
Disable the iostream timeout timer.
int ast_iostream_wait_for_input(struct ast_iostream *stream, int timeout)
Wait for input on the iostream's file descriptor.
static void iostream_dtor(void *cookie)
Generic abstraction for input/output streams.
struct ssl_ctx_st SSL_CTX
String manipulation functions.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definitions to aid in the use of thread local storage.
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
Time-related functions and macros.
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
int error(const char *format,...)
int ast_wait_for_input(int fd, int ms)
int ast_wait_for_output(int fd, int ms)
#define ast_fd_set_flags(fd, flags)
Set flags on the given file descriptor.