diff options
-rw-r--r-- | CHANGES | 3 | ||||
-rw-r--r-- | channels/chan_sip.c | 2 | ||||
-rwxr-xr-x | configure | 63 | ||||
-rw-r--r-- | configure.ac | 6 | ||||
-rw-r--r-- | include/asterisk/autoconfig.h.in | 3 | ||||
-rw-r--r-- | include/asterisk/logger.h | 7 | ||||
-rw-r--r-- | main/logger.c | 40 | ||||
-rw-r--r-- | res/ari/ari_model_validators.c | 55 | ||||
-rw-r--r-- | res/ari/ari_model_validators.h | 21 | ||||
-rw-r--r-- | res/ari/ari_websockets.c | 9 | ||||
-rw-r--r-- | res/ari/resource_asterisk.c | 26 | ||||
-rw-r--r-- | res/ari/resource_asterisk.h | 13 | ||||
-rw-r--r-- | res/res_ari_asterisk.c | 89 | ||||
-rw-r--r-- | res/res_http_websocket.c | 34 | ||||
-rw-r--r-- | res/res_pjsip_session.c | 6 | ||||
-rw-r--r-- | res/res_pjsip_transport_websocket.c | 3 | ||||
-rw-r--r-- | res/res_rtp_asterisk.c | 13 | ||||
-rw-r--r-- | rest-api/api-docs/asterisk.json | 54 |
18 files changed, 434 insertions, 13 deletions
@@ -33,6 +33,9 @@ ARI deletion. Sorcery derived objects that are manipulated by this resource must have a sorcery wizard that supports the desired operations. + * A new feature has been added that allows for the rotation of log channels + through HTTP requests. + res_pjsip ------------------ diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 9ab429e83..9ba0e192b 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -3717,7 +3717,7 @@ static int __sip_xmit(struct sip_pvt *p, struct ast_str *data) } else if (p->socket.tcptls_session) { res = sip_tcptls_write(p->socket.tcptls_session, ast_str_buffer(data), ast_str_strlen(data)); } else if (p->socket.ws_session) { - if (!(res = ast_websocket_write(p->socket.ws_session, AST_WEBSOCKET_OPCODE_TEXT, ast_str_buffer(data), ast_str_strlen(data)))) { + if (!(res = ast_websocket_write_string(p->socket.ws_session, ast_str_buffer(data)))) { /* The WebSocket API just returns 0 on success and -1 on failure, while this code expects the payload length to be returned */ res = ast_str_strlen(data); } @@ -1089,6 +1089,10 @@ PBX_DAHDI DAHDI_DIR DAHDI_INCLUDE DAHDI_LIB +PBX_OPENSSL_ECDH_AUTO +OPENSSL_ECDH_AUTO_DIR +OPENSSL_ECDH_AUTO_INCLUDE +OPENSSL_ECDH_AUTO_LIB PBX_OPENSSL_EC OPENSSL_EC_DIR OPENSSL_EC_INCLUDE @@ -8696,6 +8700,18 @@ PBX_OPENSSL_EC=0 +OPENSSL_ECDH_AUTO_DESCRIP="OpenSSL Auto ECDH Support" +OPENSSL_ECDH_AUTO_OPTION=crypto +OPENSSL_ECDH_AUTO_DIR=${CRYPTO_DIR} + +PBX_OPENSSL_ECDH_AUTO=0 + + + + + + + DAHDI_DESCRIP="DAHDI" DAHDI_OPTION="dahdi" PBX_DAHDI=0 @@ -30266,6 +30282,53 @@ fi fi +if test "$PBX_OPENSSL" = "1"; +then + + if test "x${PBX_OPENSSL_ECDH_AUTO}" != "x1" -a "${USE_OPENSSL_ECDH_AUTO}" != "no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_CTX_set_ecdh_auto declared in openssl/ssl.h" >&5 +$as_echo_n "checking for SSL_CTX_set_ecdh_auto declared in openssl/ssl.h... " >&6; } + saved_cppflags="${CPPFLAGS}" + if test "x${OPENSSL_ECDH_AUTO_DIR}" != "x"; then + OPENSSL_ECDH_AUTO_INCLUDE="-I${OPENSSL_ECDH_AUTO_DIR}/include" + fi + CPPFLAGS="${CPPFLAGS} ${OPENSSL_ECDH_AUTO_INCLUDE}" + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include <openssl/ssl.h> +int +main () +{ +#if !defined(SSL_CTX_set_ecdh_auto) + (void) SSL_CTX_set_ecdh_auto; + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + PBX_OPENSSL_ECDH_AUTO=1 + +$as_echo "#define HAVE_OPENSSL_ECDH_AUTO 1" >>confdefs.h + + + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + CPPFLAGS="${saved_cppflags}" + fi + +fi + if test "x${PBX_SRTP}" != "x1" -a "${USE_SRTP}" != "no"; then pbxlibdir="" diff --git a/configure.ac b/configure.ac index 971f9bf8a..329280924 100644 --- a/configure.ac +++ b/configure.ac @@ -414,6 +414,7 @@ AST_EXT_LIB_SETUP([CRYPT], [password and data encryption], [crypt]) AST_EXT_LIB_SETUP([CRYPTO], [OpenSSL Cryptography], [crypto]) AST_EXT_LIB_SETUP_OPTIONAL([OPENSSL_SRTP], [OpenSSL SRTP Extension Support], [CRYPTO], [crypto]) AST_EXT_LIB_SETUP_OPTIONAL([OPENSSL_EC], [OpenSSL Elliptic Curve Support], [CRYPTO], [crypto]) +AST_EXT_LIB_SETUP_OPTIONAL([OPENSSL_ECDH_AUTO], [OpenSSL Auto ECDH Support], [CRYPTO], [crypto]) AST_EXT_LIB_SETUP([DAHDI], [DAHDI], [dahdi]) AST_EXT_LIB_SETUP([FFMPEG], [Ffmpeg and avcodec], [avcodec]) AST_EXT_LIB_SETUP([GSM], [External GSM], [gsm], [, use 'internal' GSM otherwise]) @@ -2283,6 +2284,11 @@ then AST_EXT_LIB_CHECK([OPENSSL_EC], [ssl], [EC_KEY_new_by_curve_name], [openssl/ec.h], [-lcrypto]) fi +if test "$PBX_OPENSSL" = "1"; +then + AST_C_DECLARE_CHECK([OPENSSL_ECDH_AUTO], [SSL_CTX_set_ecdh_auto], [openssl/ssl.h]) +fi + AST_EXT_LIB_CHECK([SRTP], [srtp], [srtp_init], [srtp/srtp.h]) if test "$PBX_SRTP" = "1"; diff --git a/include/asterisk/autoconfig.h.in b/include/asterisk/autoconfig.h.in index 4efff1f21..542f5d2a0 100644 --- a/include/asterisk/autoconfig.h.in +++ b/include/asterisk/autoconfig.h.in @@ -548,6 +548,9 @@ /* Define to 1 if CRYPTO has the OpenSSL Elliptic Curve Support feature. */ #undef HAVE_OPENSSL_EC +/* Define if your system has SSL_CTX_set_ecdh_auto declared. */ +#undef HAVE_OPENSSL_ECDH_AUTO + /* Define to 1 if CRYPTO has the OpenSSL SRTP Extension Support feature. */ #undef HAVE_OPENSSL_SRTP diff --git a/include/asterisk/logger.h b/include/asterisk/logger.h index 22151157c..be54f47ce 100644 --- a/include/asterisk/logger.h +++ b/include/asterisk/logger.h @@ -102,6 +102,13 @@ int logger_reload(void); /*! \brief Reload logger while rotating log files */ int ast_logger_rotate(void); +/*! + * \brief Rotate the specified log channel. + * + * \param log_channel The log channel to rotate + */ +int ast_logger_rotate_channel(const char *log_channel); + void __attribute__((format(printf, 5, 6))) ast_queue_log(const char *queuename, const char *callid, const char *agent, const char *event, const char *fmt, ...); /*! diff --git a/main/logger.c b/main/logger.c index f84221f64..8fd8e50f8 100644 --- a/main/logger.c +++ b/main/logger.c @@ -933,6 +933,46 @@ int ast_logger_rotate() return reload_logger(1, NULL); } +int ast_logger_rotate_channel(const char *log_channel) +{ + struct logchannel *f; + int success = 0; + + struct ast_str *filename = ast_str_create(64); + if (!filename) { + return -1; + } + + ast_str_append(&filename, 0, "%s/%s", ast_config_AST_LOG_DIR, log_channel); + + AST_RWLIST_WRLOCK(&logchannels); + + ast_mkdir(ast_config_AST_LOG_DIR, 0644); + + AST_RWLIST_TRAVERSE(&logchannels, f, list) { + if (f->disabled) { + f->disabled = 0; /* Re-enable logging at reload */ + manager_event(EVENT_FLAG_SYSTEM, "LogChannel", "Channel: %s\r\nEnabled: Yes\r\n", + f->filename); + } + if (f->fileptr && (f->fileptr != stdout) && (f->fileptr != stderr)) { + fclose(f->fileptr); /* Close file */ + f->fileptr = NULL; + if (strcmp(ast_str_buffer(filename), f->filename) == 0) { + rotate_file(f->filename); + success = 1; + } + } + } + + init_logger_chain(1 /* locked */, NULL); + + AST_RWLIST_UNLOCK(&logchannels); + ast_free(filename); + + return success; +} + static char *handle_logger_set_level(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { int x; diff --git a/res/ari/ari_model_validators.c b/res/ari/ari_model_validators.c index 667589601..120daf546 100644 --- a/res/ari/ari_model_validators.c +++ b/res/ari/ari_model_validators.c @@ -362,6 +362,61 @@ ari_validator ast_ari_validate_config_tuple_fn(void) return ast_ari_validate_config_tuple; } +int ast_ari_validate_log_channel(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_logging_levels = 0; + int has_name = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("logging_levels", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_logging_levels = 1; + prop_is_valid = ast_ari_validate_list( + ast_json_object_iter_value(iter), + ast_ari_validate_string); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI LogChannel field logging_levels failed validation\n"); + res = 0; + } + } else + if (strcmp("name", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_name = 1; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI LogChannel field name failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI LogChannel has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_logging_levels) { + ast_log(LOG_ERROR, "ARI LogChannel missing required field logging_levels\n"); + res = 0; + } + + if (!has_name) { + ast_log(LOG_ERROR, "ARI LogChannel missing required field name\n"); + res = 0; + } + + return res; +} + +ari_validator ast_ari_validate_log_channel_fn(void) +{ + return ast_ari_validate_log_channel; +} + int ast_ari_validate_module(struct ast_json *json) { int res = 1; diff --git a/res/ari/ari_model_validators.h b/res/ari/ari_model_validators.h index e122ded34..fa393448d 100644 --- a/res/ari/ari_model_validators.h +++ b/res/ari/ari_model_validators.h @@ -225,6 +225,24 @@ int ast_ari_validate_config_tuple(struct ast_json *json); ari_validator ast_ari_validate_config_tuple_fn(void); /*! + * \brief Validator for LogChannel. + * + * Details of an Asterisk log channel + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ast_ari_validate_log_channel(struct ast_json *json); + +/*! + * \brief Function pointer to ast_ari_validate_log_channel(). + * + * See \ref ast_ari_model_validators.h for more details. + */ +ari_validator ast_ari_validate_log_channel_fn(void); + +/*! * \brief Validator for Module. * * Details of an Asterisk module @@ -1283,6 +1301,9 @@ ari_validator ast_ari_validate_application_fn(void); * ConfigTuple * - attribute: string (required) * - value: string (required) + * LogChannel + * - logging_levels: List[string] (required) + * - name: string (required) * Module * - description: string (required) * - name: string (required) diff --git a/res/ari/ari_websockets.c b/res/ari/ari_websockets.c index f3b764bf1..39c6dcac9 100644 --- a/res/ari/ari_websockets.c +++ b/res/ari/ari_websockets.c @@ -163,9 +163,7 @@ int ast_ari_websocket_session_write(struct ast_ari_websocket_session *session, #ifdef AST_DEVMODE if (!session->validator(message)) { ast_log(LOG_ERROR, "Outgoing message failed validation\n"); - return ast_websocket_write(session->ws_session, - AST_WEBSOCKET_OPCODE_TEXT, VALIDATION_FAILED, - strlen(VALIDATION_FAILED)); + return ast_websocket_write_string(session->ws_session, VALIDATION_FAILED); } #endif @@ -176,9 +174,8 @@ int ast_ari_websocket_session_write(struct ast_ari_websocket_session *session, return -1; } - ast_debug(3, "Examining ARI event: \n%s\n", str); - if (ast_websocket_write(session->ws_session, - AST_WEBSOCKET_OPCODE_TEXT, str, strlen(str))) { + ast_debug(3, "Examining ARI event (length %zu): \n%s\n", strlen(str), str); + if (ast_websocket_write_string(session->ws_session, str)) { ast_log(LOG_NOTICE, "Problem occurred during websocket write, websocket closed\n"); return -1; } diff --git a/res/ari/resource_asterisk.c b/res/ari/resource_asterisk.c index 2b6b6bc6e..e227951e2 100644 --- a/res/ari/resource_asterisk.c +++ b/res/ari/resource_asterisk.c @@ -33,6 +33,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/ast_version.h" #include "asterisk/buildinfo.h" +#include "asterisk/logger.h" #include "asterisk/module.h" #include "asterisk/paths.h" #include "asterisk/pbx.h" @@ -627,6 +628,31 @@ void ast_ari_asterisk_reload_module(struct ast_variable *headers, ast_ari_response_no_content(response); } +void ast_ari_asterisk_rotate_log(struct ast_variable *headers, + struct ast_ari_asterisk_rotate_log_args *args, + struct ast_ari_response *response) +{ + int success; + + ast_assert(response != NULL); + + success = ast_logger_rotate_channel(args->log_channel_name); + + if (success == 0) { + ast_ari_response_error( + response, 404, "Not Found", + "Log channel does not exist"); + return; + } else if (success == -1) { + ast_ari_response_error( + response, 500, "Internal Server Error", + "Allocation failed"); + return; + } + + ast_ari_response_no_content(response); +} + void ast_ari_asterisk_get_global_var(struct ast_variable *headers, struct ast_ari_asterisk_get_global_var_args *args, struct ast_ari_response *response) diff --git a/res/ari/resource_asterisk.h b/res/ari/resource_asterisk.h index 1afc09317..e271b0547 100644 --- a/res/ari/resource_asterisk.h +++ b/res/ari/resource_asterisk.h @@ -194,6 +194,19 @@ struct ast_ari_asterisk_reload_module_args { * \param[out] response HTTP response */ void ast_ari_asterisk_reload_module(struct ast_variable *headers, struct ast_ari_asterisk_reload_module_args *args, struct ast_ari_response *response); +/*! Argument struct for ast_ari_asterisk_rotate_log() */ +struct ast_ari_asterisk_rotate_log_args { + /*! Log channel's name */ + const char *log_channel_name; +}; +/*! + * \brief Rotates a log channel. + * + * \param headers HTTP headers + * \param args Swagger parameters + * \param[out] response HTTP response + */ +void ast_ari_asterisk_rotate_log(struct ast_variable *headers, struct ast_ari_asterisk_rotate_log_args *args, struct ast_ari_response *response); /*! Argument struct for ast_ari_asterisk_get_global_var() */ struct ast_ari_asterisk_get_global_var_args { /*! The variable to get */ diff --git a/res/res_ari_asterisk.c b/res/res_ari_asterisk.c index ea8ddbb35..d532da9e8 100644 --- a/res/res_ari_asterisk.c +++ b/res/res_ari_asterisk.c @@ -721,6 +721,65 @@ static void ast_ari_asterisk_reload_module_cb( fin: __attribute__((unused)) return; } +/*! + * \brief Parameter parsing callback for /asterisk/logging/{logChannelName}/rotate. + * \param get_params GET parameters in the HTTP request. + * \param path_vars Path variables extracted from the request. + * \param headers HTTP headers. + * \param[out] response Response to the HTTP request. + */ +static void ast_ari_asterisk_rotate_log_cb( + struct ast_tcptls_session_instance *ser, + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct ast_ari_response *response) +{ + struct ast_ari_asterisk_rotate_log_args args = {}; + struct ast_variable *i; + RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + + for (i = path_vars; i; i = i->next) { + if (strcmp(i->name, "logChannelName") == 0) { + args.log_channel_name = (i->value); + } else + {} + } + ast_ari_asterisk_rotate_log(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 0: /* Implementation is still a stub, or the code wasn't set */ + is_valid = response->message == NULL; + break; + case 500: /* Internal Server Error */ + case 501: /* Not Implemented */ + case 404: /* Log channel does not exist. */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ast_ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /asterisk/logging/{logChannelName}/rotate\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /asterisk/logging/{logChannelName}/rotate\n"); + ast_ari_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ + +fin: __attribute__((unused)) + return; +} int ast_ari_asterisk_get_global_var_parse_body( struct ast_json *body, struct ast_ari_asterisk_get_global_var_args *args) @@ -989,6 +1048,32 @@ static struct stasis_rest_handlers asterisk_modules = { .children = { &asterisk_modules_moduleName, } }; /*! \brief REST handler for /api-docs/asterisk.{format} */ +static struct stasis_rest_handlers asterisk_logging_logChannelName_rotate = { + .path_segment = "rotate", + .callbacks = { + [AST_HTTP_PUT] = ast_ari_asterisk_rotate_log_cb, + }, + .num_children = 0, + .children = { } +}; +/*! \brief REST handler for /api-docs/asterisk.{format} */ +static struct stasis_rest_handlers asterisk_logging_logChannelName = { + .path_segment = "logChannelName", + .is_wildcard = 1, + .callbacks = { + }, + .num_children = 1, + .children = { &asterisk_logging_logChannelName_rotate, } +}; +/*! \brief REST handler for /api-docs/asterisk.{format} */ +static struct stasis_rest_handlers asterisk_logging = { + .path_segment = "logging", + .callbacks = { + }, + .num_children = 1, + .children = { &asterisk_logging_logChannelName, } +}; +/*! \brief REST handler for /api-docs/asterisk.{format} */ static struct stasis_rest_handlers asterisk_variable = { .path_segment = "variable", .callbacks = { @@ -1003,8 +1088,8 @@ static struct stasis_rest_handlers asterisk = { .path_segment = "asterisk", .callbacks = { }, - .num_children = 4, - .children = { &asterisk_config,&asterisk_info,&asterisk_modules,&asterisk_variable, } + .num_children = 5, + .children = { &asterisk_config,&asterisk_info,&asterisk_modules,&asterisk_logging,&asterisk_variable, } }; static int load_module(void) diff --git a/res/res_http_websocket.c b/res/res_http_websocket.c index 144c08d0e..db9c50a28 100644 --- a/res/res_http_websocket.c +++ b/res/res_http_websocket.c @@ -298,6 +298,24 @@ int AST_OPTIONAL_API_NAME(ast_websocket_close)(struct ast_websocket *session, ui return res; } +static const char *opcode_map[] = { + [AST_WEBSOCKET_OPCODE_CONTINUATION] = "continuation", + [AST_WEBSOCKET_OPCODE_TEXT] = "text", + [AST_WEBSOCKET_OPCODE_BINARY] = "binary", + [AST_WEBSOCKET_OPCODE_CLOSE] = "close", + [AST_WEBSOCKET_OPCODE_PING] = "ping", + [AST_WEBSOCKET_OPCODE_PONG] = "pong", +}; + +static const char *websocket_opcode2str(enum ast_websocket_opcode opcode) +{ + if (opcode < AST_WEBSOCKET_OPCODE_CONTINUATION || + opcode > AST_WEBSOCKET_OPCODE_PONG) { + return "<unknown>"; + } else { + return opcode_map[opcode]; + } +} /*! \brief Write function for websocket traffic */ int AST_OPTIONAL_API_NAME(ast_websocket_write)(struct ast_websocket *session, enum ast_websocket_opcode opcode, char *payload, uint64_t actual_length) @@ -306,6 +324,9 @@ int AST_OPTIONAL_API_NAME(ast_websocket_write)(struct ast_websocket *session, en char *frame; uint64_t length; + ast_debug(3, "Writing websocket %s frame, length %" PRIu64 "\n", + websocket_opcode2str(opcode), actual_length); + if (actual_length < 126) { length = actual_length; } else if (actual_length < (1 << 16)) { @@ -1354,8 +1375,19 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read_string) int AST_OPTIONAL_API_NAME(ast_websocket_write_string) (struct ast_websocket *ws, const char *buf) { + uint64_t len = strlen(buf); + + ast_debug(3, "Writing websocket string of length %" PRIu64 "\n", len); + + /* We do not pass strlen(buf) to ast_websocket_write() directly because the + * size_t returned by strlen() may not require the same storage size + * as the uint64_t that ast_websocket_write() uses. This normally + * would not cause a problem, but since ast_websocket_write() uses + * the optional API, this function call goes through a series of macros + * that may cause a 32-bit to 64-bit conversion to go awry. + */ return ast_websocket_write(ws, AST_WEBSOCKET_OPCODE_TEXT, - (char *)buf, strlen(buf)); + (char *)buf, len); } static int load_module(void) diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index 5eb72b45a..539bfc1fa 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -2681,8 +2681,10 @@ static void session_inv_on_media_update(pjsip_inv_session *inv, pj_status_t stat struct ast_sip_session *session = inv->mod_data[session_module.id]; const pjmedia_sdp_session *local, *remote; - if (!session->channel) { - /* If we don't have a channel. We really don't care about media updates. + if (!session || !session->channel) { + /* + * If we don't have a session or channel then we really + * don't care about media updates. * Just ignore */ return; diff --git a/res/res_pjsip_transport_websocket.c b/res/res_pjsip_transport_websocket.c index be3046889..f2c16a118 100644 --- a/res/res_pjsip_transport_websocket.c +++ b/res/res_pjsip_transport_websocket.c @@ -63,8 +63,9 @@ static pj_status_t ws_send_msg(pjsip_transport *transport, pjsip_transport_callback callback) { struct ws_transport *wstransport = (struct ws_transport *)transport; + uint64_t len = tdata->buf.cur - tdata->buf.start; - if (ast_websocket_write(wstransport->ws_session, AST_WEBSOCKET_OPCODE_TEXT, tdata->buf.start, (int)(tdata->buf.cur - tdata->buf.start))) { + if (ast_websocket_write(wstransport->ws_session, AST_WEBSOCKET_OPCODE_TEXT, tdata->buf.start, len)) { return PJ_EUNKNOWN; } diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c index 5d206c1a0..462091778 100644 --- a/res/res_rtp_asterisk.c +++ b/res/res_rtp_asterisk.c @@ -1268,6 +1268,9 @@ static int ast_rtp_dtls_set_configuration(struct ast_rtp_instance *instance, con { struct ast_rtp *rtp = ast_rtp_instance_get_data(instance); int res; +#ifndef HAVE_OPENSSL_ECDH_AUTO + EC_KEY *ecdh; +#endif if (!dtls_cfg->enabled) { return 0; @@ -1288,6 +1291,16 @@ static int ast_rtp_dtls_set_configuration(struct ast_rtp_instance *instance, con SSL_CTX_set_read_ahead(rtp->ssl_ctx, 1); +#ifdef HAVE_OPENSSL_ECDH_AUTO + SSL_CTX_set_ecdh_auto(rtp->ssl_ctx, 1); +#else + ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + if (ecdh) { + SSL_CTX_set_tmp_ecdh(rtp->ssl_ctx, ecdh); + EC_KEY_free(ecdh); + } +#endif + rtp->dtls_verify = dtls_cfg->verify; SSL_CTX_set_verify(rtp->ssl_ctx, (rtp->dtls_verify & AST_RTP_DTLS_VERIFY_FINGERPRINT) || (rtp->dtls_verify & AST_RTP_DTLS_VERIFY_CERTIFICATE) ? diff --git a/rest-api/api-docs/asterisk.json b/rest-api/api-docs/asterisk.json index cc1e3b821..6e0dd6c0d 100644 --- a/rest-api/api-docs/asterisk.json +++ b/rest-api/api-docs/asterisk.json @@ -297,6 +297,34 @@ ] }, { + "path": "/asterisk/logging/{logChannelName}/rotate", + "description": "Asterisk log channel", + "operations": [ + { + "httpMethod": "PUT", + "summary": "Rotates a log channel.", + "nickname": "rotateLog", + "responseClass": "void", + "parameters": [ + { + "name": "logChannelName", + "description": "Log channel's name", + "paramType": "path", + "required": true, + "allowMultiple": false, + "dataType": "string" + } + ], + "errorResponses": [ + { + "code": 404, + "reason": "Log channel does not exist." + } + ] + } + ] + }, + { "path": "/asterisk/variable", "description": "Global variables", "operations": [ @@ -533,6 +561,32 @@ } } }, + "LogChannel": { + "id": "LogChannel", + "description": "Details of an Asterisk log channel", + "properties": { + "name": { + "type": "string", + "description": "The log channel path", + "required": true + }, + "type": { + "type": "string", + "description": "Types of logs for the log channel", + "required": true + }, + "status": { + "type": "string", + "description": "Whether or not a log type is enabled", + "required": true + }, + "configuration": { + "type": "string", + "description": "The various log levels", + "required": true + } + } + }, "Variable": { "id": "Variable", "description": "The value of a channel variable", |