diff options
4 files changed, 137 insertions, 56 deletions
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c index a0530007b..aeb060569 100644 --- a/channels/chan_skinny.c +++ b/channels/chan_skinny.c @@ -6658,7 +6658,7 @@ static int handle_capabilities_res_message(struct skinny_req *req, struct skinny #ifdef AST_DEVMODE struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN); #endif - + if (!codecs) { return 0; @@ -7499,6 +7499,8 @@ static void skinny_session_cleanup(void *data) destroy_session(s); } +#define PACKET_TIMEOUT 10000 + static void *skinny_session(void *data) { int res; @@ -7545,78 +7547,86 @@ static void *skinny_session(void *data) } } - if (fds[0].revents) { + if (!fds[0].revents) { + continue; + } + ast_debug(1, "Reading header\n"); - if (!(req = ast_calloc(1, SKINNY_MAX_PACKET))) { - ast_log(LOG_WARNING, "Unable to allocated memorey for skinny_req.\n"); - break; - } + if (!(req = ast_calloc(1, SKINNY_MAX_PACKET))) { + ast_log(LOG_WARNING, "Unable to allocated memorey for skinny_req.\n"); + break; + } - ast_mutex_lock(&s->lock); - s->lockstate = 1; + ast_mutex_lock(&s->lock); + s->lockstate = 1; - if ((res = read(s->fd, req, skinny_header_size)) != skinny_header_size) { - if (res < 0) { - ast_log(LOG_WARNING, "Header read() returned error: %s\n", strerror(errno)); - } else { - ast_log(LOG_WARNING, "Unable to read header. Only found %d bytes.\n", res); - } - break; + if ((res = read(s->fd, req, skinny_header_size)) != skinny_header_size) { + if (res < 0) { + ast_log(LOG_WARNING, "Header read() returned error: %s\n", strerror(errno)); + } else { + ast_log(LOG_WARNING, "Unable to read header. Only found %d bytes.\n", res); } + break; + } - eventmessage = letohl(req->e); - if (eventmessage < 0) { - ast_log(LOG_ERROR, "Event Message is NULL from socket %d, This is bad\n", s->fd); - break; - } + eventmessage = letohl(req->e); + if (eventmessage < 0) { + ast_log(LOG_ERROR, "Event Message is NULL from socket %d, This is bad\n", s->fd); + break; + } - dlen = letohl(req->len) - 4; - if (dlen < 0) { - ast_log(LOG_WARNING, "Skinny Client sent invalid data.\n"); - break; - } - if (dlen > (SKINNY_MAX_PACKET - skinny_header_size)) { - ast_log(LOG_WARNING, "Skinny packet too large (%d bytes), max length(%d bytes)\n", dlen+8, SKINNY_MAX_PACKET); - break; - } + dlen = letohl(req->len) - 4; + if (dlen < 0) { + ast_log(LOG_WARNING, "Skinny Client sent invalid data.\n"); + break; + } + if (dlen > (SKINNY_MAX_PACKET - skinny_header_size)) { + ast_log(LOG_WARNING, "Skinny packet too large (%d bytes), max length(%d bytes)\n", dlen+8, SKINNY_MAX_PACKET); + break; + } - bytesread = 0; - while (1) { - if ((res = read(s->fd, ((char*)&req->data)+bytesread, dlen-bytesread)) < 0) { - ast_log(LOG_WARNING, "Data read() returned error: %s\n", strerror(errno)); - break; - } - bytesread += res; - if (bytesread >= dlen) { - if (res < bytesread) { - ast_log(LOG_WARNING, "Rest of partial data received.\n"); - } - if (bytesread > dlen) { - ast_log(LOG_WARNING, "Client sent wrong amount of data (%d), expected (%d).\n", bytesread, dlen); - res = -1; - } - break; - } + ast_debug(1, "Read header: Message ID: 0x%04x, %d bytes in packet\n", eventmessage, dlen); - ast_log(LOG_WARNING, "Partial data received, waiting (%d bytes read of %d)\n", bytesread, dlen); - if (sched_yield() < 0) { - ast_log(LOG_WARNING, "Data yield() returned error: %s\n", strerror(errno)); - res = -1; - break; + bytesread = 0; + while (bytesread < dlen) { + ast_debug(1, "Waiting %dms for %d bytes of %d\n", PACKET_TIMEOUT, dlen - bytesread, dlen); + fds[0].revents = 0; + res = ast_poll(fds, 1, PACKET_TIMEOUT); + if (res <= 0) { + if (res == 0) { + ast_debug(1, "Poll timed out waiting for %d bytes\n", dlen - bytesread); + } else { + ast_log(LOG_WARNING, "Poll failed waiting for %d bytes: %s\n", + dlen - bytesread, strerror(errno)); } + ast_verb(3, "Ending Skinny session from %s (bad input)\n", ast_inet_ntoa(s->sin.sin_addr)); + res = -1; + + break; + } + if (!fds[0].revents) { + continue; } - s->lockstate = 0; - ast_mutex_unlock(&s->lock); + res = read(s->fd, ((char*)&req->data)+bytesread, dlen-bytesread); if (res < 0) { + ast_log(LOG_WARNING, "Data read() returned error: %s\n", strerror(errno)); break; } + bytesread += res; + ast_debug(1, "Read %d bytes. %d of %d now read\n", res, bytesread, dlen); + } - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); - res = handle_message(req, s); - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + s->lockstate = 0; + ast_mutex_unlock(&s->lock); + if (res < 0) { + break; } + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + res = handle_message(req, s); + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + if (req) { ast_free(req); req = NULL; diff --git a/res/res_hep_rtcp.c b/res/res_hep_rtcp.c index 395031a3d..31b9c485b 100644 --- a/res/res_hep_rtcp.c +++ b/res/res_hep_rtcp.c @@ -181,6 +181,7 @@ static int unload_module(void) } AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "RTCP HEPv3 Logger", + .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, diff --git a/third-party/pjproject/patches/0058-Parse-zero-length-multipart-body-parts-correctly.patch b/third-party/pjproject/patches/0058-Parse-zero-length-multipart-body-parts-correctly.patch new file mode 100644 index 000000000..49334c354 --- /dev/null +++ b/third-party/pjproject/patches/0058-Parse-zero-length-multipart-body-parts-correctly.patch @@ -0,0 +1,41 @@ +From f0c717463d569f87a16f9b014033c8ca8939a7b4 Mon Sep 17 00:00:00 2001 +From: Mark Michelson <mmichelson@digium.com> +Date: Thu, 13 Apr 2017 16:59:40 -0500 +Subject: [PATCH] Parse zero-length multipart body parts correctly. + +The calculation of end_body could result in a negative length being +passed to multipart_body_parse_part(). +--- + pjsip/src/pjsip/sip_multipart.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/pjsip/src/pjsip/sip_multipart.c b/pjsip/src/pjsip/sip_multipart.c +index 8351f7e..b302139 100644 +--- a/pjsip/src/pjsip/sip_multipart.c ++++ b/pjsip/src/pjsip/sip_multipart.c +@@ -653,13 +653,15 @@ PJ_DEF(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool, + + end_body = curptr; + +- /* The newline preceeding the delimiter is conceptually part of +- * the delimiter, so trim it from the body. +- */ +- if (*(end_body-1) == '\n') +- --end_body; +- if (*(end_body-1) == '\r') +- --end_body; ++ if (end_body > start_body) { ++ /* The newline preceeding the delimiter is conceptually part of ++ * the delimiter, so trim it from the body. ++ */ ++ if (*(end_body-1) == '\n') ++ --end_body; ++ if (*(end_body-1) == '\r') ++ --end_body; ++ } + + /* Now that we have determined the part's boundary, parse it + * to get the header and body part of the part. +-- +1.9.1 + diff --git a/third-party/pjproject/patches/0059-Ensure-2543-transaction-key-buffer-is-large-enough.patch b/third-party/pjproject/patches/0059-Ensure-2543-transaction-key-buffer-is-large-enough.patch new file mode 100644 index 000000000..eb5a7db73 --- /dev/null +++ b/third-party/pjproject/patches/0059-Ensure-2543-transaction-key-buffer-is-large-enough.patch @@ -0,0 +1,29 @@ +From b5f0f8868363c482a2c4ce343e3ee6ad256b0708 Mon Sep 17 00:00:00 2001 +From: Mark Michelson <mmichelson@digium.com> +Date: Thu, 13 Apr 2017 16:20:07 -0500 +Subject: [PATCH] Ensure 2543 transaction key buffer is large enough. + +The CSeq method length needs to be factored into the allocated buffer +length. Otherwise, the buffer may not be large enough to accommodate the +entire key. +--- + pjsip/src/pjsip/sip_transaction.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c +index c1750dc..2200d8d 100644 +--- a/pjsip/src/pjsip/sip_transaction.c ++++ b/pjsip/src/pjsip/sip_transaction.c +@@ -288,7 +288,8 @@ static pj_status_t create_tsx_key_2543( pj_pool_t *pool, + host = &rdata->msg_info.via->sent_by.host; + + /* Calculate length required. */ +- len_required = 9 + /* CSeq number */ ++ len_required = method->name.slen + /* Method */ ++ 9 + /* CSeq number */ + rdata->msg_info.from->tag.slen + /* From tag. */ + rdata->msg_info.cid->id.slen + /* Call-ID */ + host->slen + /* Via host. */ +-- +1.9.1 + |