From 069a0b75930979b747e952cb8e10817aa7316aea Mon Sep 17 00:00:00 2001 From: Sean Bright Date: Mon, 30 Apr 2018 16:15:49 -0400 Subject: [PATCH] iostreams: Add some documentation for the ast_iostream_* functions Change-Id: Id71b87637f0a484eb5a1cd26c3d1c7c15c7dcf26 --- include/asterisk/iostream.h | 164 +++++++++++++++++++++++++++++++++--- main/iostream.c | 40 ++++----- 2 files changed, 174 insertions(+), 30 deletions(-) diff --git a/include/asterisk/iostream.h b/include/asterisk/iostream.h index e9816ac9b1..b4cdeb2dc0 100644 --- a/include/asterisk/iostream.h +++ b/include/asterisk/iostream.h @@ -44,7 +44,7 @@ struct ast_iostream; /*! * \brief Disable the iostream timeout timer. * - * \param stream iostream control data. + * \param stream A pointer to an iostream * * \return Nothing */ @@ -53,7 +53,7 @@ void ast_iostream_set_timeout_disable(struct ast_iostream *stream); /*! * \brief Set the iostream inactivity timeout timer. * - * \param stream iostream control data. + * \param stream A pointer to an iostream * \param timeout Number of milliseconds to wait for data transfer with the peer. * * \details This is basically how much time we are willing to spend @@ -66,12 +66,30 @@ void ast_iostream_set_timeout_disable(struct ast_iostream *stream); */ void ast_iostream_set_timeout_inactivity(struct ast_iostream *stream, int timeout); +/*! + * \brief Set the iostream inactivity & idle timeout timers. + * + * \param stream A pointer to an iostream + * \param timeout Number of milliseconds to wait for initial data transfer with + * the peer. + * \param timeout_reset Number of milliseconds to wait for subsequent data + * transfer with the peer. + * + * \details As an example, if you want to timeout a peer if they do not send an + * initial message within 5 seconds or if they do not send a message at + * least every 30 seconds, you would set \a timeout to \c 5000 and + * \a timeout_reset to \c 30000. + * + * \note Setting either of these timeouts to -1 will disable them. + * + * \return Nothing + */ void ast_iostream_set_timeout_idle_inactivity(struct ast_iostream *stream, int timeout, int timeout_reset); /*! * \brief Set the iostream I/O sequence timeout timer. * - * \param stream iostream control data. + * \param stream A pointer to an iostream * \param start Time the I/O sequence timer starts. * \param timeout Number of milliseconds from the start time before timeout. * @@ -89,7 +107,7 @@ void ast_iostream_set_timeout_sequence(struct ast_iostream *stream, struct timev /*! * \brief Set the iostream if it can exclusively depend upon the set timeouts. * - * \param stream iostream control data. + * \param stream A pointer to an iostream * \param exclusive_input TRUE if stream can exclusively wait for fd input. * Otherwise, the stream will not wait for fd input. It will wait while * trying to send data. @@ -100,20 +118,146 @@ void ast_iostream_set_timeout_sequence(struct ast_iostream *stream, struct timev */ void ast_iostream_set_exclusive_input(struct ast_iostream *stream, int exclusive_input); +/*! + * \brief Get an iostream's file descriptor. + * + * \param stream A pointer to an iostream + * + * \return The file descriptor for the given iostream, or -1 if the iostream has no open + * file descriptor. + */ int ast_iostream_get_fd(struct ast_iostream *stream); + +/*! + * \brief Make an iostream non-blocking. + * + * \param stream A pointer to an iostream + * + * \return Nothing + */ void ast_iostream_nonblock(struct ast_iostream *stream); -SSL* ast_iostream_get_ssl(struct ast_iostream *stream); +/*! + * \brief Get a pointer to an iostream's OpenSSL \c SSL structure + * + * \param stream A pointer to an iostream + * + * \return A pointer to the OpenSSL \c SSL structure for the given iostream, or + * \c NULL if TLS has not been initiated. + * + * \note If OpenSSL support is not included in the build, this will always return + * \c NULL. + */ +SSL *ast_iostream_get_ssl(struct ast_iostream *stream); + +/*! + * \brief Read data from an iostream. + * + * \param stream A pointer to an iostream + * \param buffer Pointer to a buffer to store the read bytes. + * \param count The number of bytes to read. + * + * \return Upon successful completion, returns a non-negative integer indicating + * the number of bytes actually read. Otherwise, returns -1 and may set + * errno to indicate the error. + */ +ssize_t ast_iostream_read(struct ast_iostream *stream, void *buffer, size_t count); + +/*! + * \brief Read a LF-terminated string from an iostream. + * + * \param stream A pointer to an iostream + * \param buffer Pointer to a buffer to store the read bytes. + * \param size The total size of \a buffer in bytes. + * + * \return The number of bytes stored in \a buffer, excluding the null byte used + * to terminate the string. If the size of \a buffer (indicated by the + * caller with the \a size argument) is not sufficient to store the + * entire line it will be truncated to fit the available space. The + * contents of \a buffer will always be terminated with a null byte. In + * the case of an error, \c -1 will be returned and \c errno may be set + * indicating the error. + */ +ssize_t ast_iostream_gets(struct ast_iostream *stream, char *buffer, size_t size); -ssize_t ast_iostream_read(struct ast_iostream *stream, void *buf, size_t count); -ssize_t ast_iostream_gets(struct ast_iostream *stream, char *buf, size_t count); +/*! + * \brief Discard the specified number of bytes from an iostream. + * + * \param stream A pointer to an iostream + * \param count The number of bytes to discard. + * + * \return Upon successful completion, returns the number of bytes discarded. + * Otherwise, \c -1 is returned and \c errno may be set indicating the + * error. + */ ssize_t ast_iostream_discard(struct ast_iostream *stream, size_t count); -ssize_t ast_iostream_write(struct ast_iostream *stream, const void *buf, size_t count); + +/*! + * \brief Write data to an iostream. + * + * \param stream A pointer to an iostream + * \param buffer Pointer to a buffer from which to read bytes. + * \param count The number of bytes from \a buffer to write. + * + * \return Upon successful completion, returns the number of bytes actually + * written to the iostream. This number shall never be greater than + * \a count. Otherwise, returns \c -1 and may set \c errno to indicate + * the error. + */ +ssize_t ast_iostream_write(struct ast_iostream *stream, const void *buffer, size_t count); + +/*! + * \brief Write a formatted string to an iostream. + * + * \param stream A pointer to an iostream + * \param format A format string, as documented by printf(3) + * \param ... Arguments for the provided \a format string + * + * \return The number of bytes written, or \c -1 if an error occurs. Note that if + * \c -1 is returned, the number of bytes written to the iostream is + * unspecified. + */ ssize_t __attribute__((format(printf, 2, 3))) ast_iostream_printf( - struct ast_iostream *stream, const char *fmt, ...); + struct ast_iostream *stream, const char *format, ...); -struct ast_iostream* ast_iostream_from_fd(int *fd); +/*! + * \brief Create an iostream from a file descriptor. + * + * \param fd A pointer to an open file descriptor + * + * \return A newly allocated iostream or \c NULL if allocation fails. + */ +struct ast_iostream *ast_iostream_from_fd(int *fd); + +/*! + * \brief Begin TLS on an iostream. + * + * \param stream A pointer to an iostream pointer + * \param ctx A pointer to an \c SSL_CTX which will be passed to \c SSL_new() + * \param client Non-zero to indicate that we are the client, zero to indicate + * that we are the server. + * + * \retval 0 success + * \retval -1 failure + * + * \note The iostream that is passed in \a stream may be replaced with a + * different one before this function returns. + * \note On failure, \c errno may be set providing additional information on why + * the failure occurred. + */ int ast_iostream_start_tls(struct ast_iostream **stream, SSL_CTX *ctx, int client); + +/*! + * \brief Close an iostream. + * + * \param stream A pointer to an iostream + * + * \retval 0 success + * \retval -1 failure + * + * \note On failure, \c errno may be set providing additional information on why + * the failure occurred. + */ int ast_iostream_close(struct ast_iostream *stream); #endif /* _ASTERISK_IOSTREAM_H */ diff --git a/main/iostream.c b/main/iostream.c index aaa74fae1a..4cddd43b6b 100644 --- a/main/iostream.c +++ b/main/iostream.c @@ -238,9 +238,9 @@ static ssize_t iostream_read(struct ast_iostream *stream, void *buf, size_t size } } -ssize_t ast_iostream_read(struct ast_iostream *stream, void *buf, size_t size) +ssize_t ast_iostream_read(struct ast_iostream *stream, void *buffer, size_t count) { - if (!size) { + if (!count) { /* You asked for no data you got no data. */ return 0; } @@ -252,20 +252,20 @@ ssize_t ast_iostream_read(struct ast_iostream *stream, void *buf, size_t size) /* Get any remains from the read buffer */ if (stream->rbuflen) { - size_t r = size; + size_t r = count; if (r > stream->rbuflen) { r = stream->rbuflen; } - memcpy(buf, stream->rbufhead, r); + memcpy(buffer, stream->rbufhead, r); stream->rbuflen -= r; stream->rbufhead += r; return r; } - return iostream_read(stream, buf, size); + return iostream_read(stream, buffer, count); } -ssize_t ast_iostream_gets(struct ast_iostream *stream, char *buf, size_t count) +ssize_t ast_iostream_gets(struct ast_iostream *stream, char *buffer, size_t size) { ssize_t r; char *newline; @@ -275,15 +275,15 @@ ssize_t ast_iostream_gets(struct ast_iostream *stream, char *buf, size_t count) newline = memchr(stream->rbufhead, '\n', stream->rbuflen); if (newline) { r = newline - stream->rbufhead + 1; - if (r > count-1) { - r = count-1; + if (r > size-1) { + r = size-1; } break; } /* Enough data? */ - if (stream->rbuflen >= count - 1) { - r = count - 1; + if (stream->rbuflen >= size - 1) { + r = size - 1; break; } @@ -301,8 +301,8 @@ ssize_t ast_iostream_gets(struct ast_iostream *stream, char *buf, size_t count) } while (1); /* Return r bytes with termination byte */ - memcpy(buf, stream->rbufhead, r); - buf[r] = 0; + memcpy(buffer, stream->rbufhead, r); + buffer[r] = 0; stream->rbuflen -= r; stream->rbufhead += r; @@ -326,7 +326,7 @@ ssize_t ast_iostream_discard(struct ast_iostream *stream, size_t size) return size; } -ssize_t ast_iostream_write(struct ast_iostream *stream, const void *buf, size_t size) +ssize_t ast_iostream_write(struct ast_iostream *stream, const void *buffer, size_t size) { struct timeval start; int ms; @@ -357,7 +357,7 @@ ssize_t ast_iostream_write(struct ast_iostream *stream, const void *buf, size_t for (;;) { int sslerr; char err[256]; - res = SSL_write(stream->ssl, buf + written, remaining); + res = SSL_write(stream->ssl, buffer + written, remaining); if (res == remaining) { /* Everything was written. */ return size; @@ -414,7 +414,7 @@ ssize_t ast_iostream_write(struct ast_iostream *stream, const void *buf, size_t written = 0; remaining = size; for (;;) { - res = write(stream->fd, buf + written, remaining); + res = write(stream->fd, buffer + written, remaining); if (res == remaining) { /* Yay everything was written. */ return size; @@ -443,14 +443,14 @@ ssize_t ast_iostream_write(struct ast_iostream *stream, const void *buf, size_t } } -ssize_t ast_iostream_printf(struct ast_iostream *stream, const char *fmt, ...) +ssize_t ast_iostream_printf(struct ast_iostream *stream, const char *format, ...) { char sbuf[512], *buf = sbuf; int len, len2, ret = -1; va_list va; - va_start(va, fmt); - len = vsnprintf(buf, sizeof(sbuf), fmt, va); + va_start(va, format); + len = vsnprintf(buf, sizeof(sbuf), format, va); va_end(va); if (len > sizeof(sbuf) - 1) { @@ -461,8 +461,8 @@ ssize_t ast_iostream_printf(struct ast_iostream *stream, const char *fmt, ...) if (!buf) { return -1; } - va_start(va, fmt); - len2 = vsnprintf(buf, buf_len, fmt, va); + va_start(va, format); + len2 = vsnprintf(buf, buf_len, format, va); va_end(va); if (len2 != len) { goto error;