From 3484fe8a9ef9d8f43fcf9801e1381694b136d272 Mon Sep 17 00:00:00 2001 From: russell Date: Wed, 30 Jul 2008 20:38:35 +0000 Subject: Merged revisions 134595 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r134595 | russell | 2008-07-30 15:37:17 -0500 (Wed, 30 Jul 2008) | 6 lines Reduce stack consumption by 12.5% of the max stack size to fix a crash when compiled with LOW_MEMORY. (closes issue #13154) Reported by: edantie ........ git-svn-id: http://svn.digium.com/svn/asterisk/trunk@134596 f38db490-d61c-443f-a65b-d21fe96a405b --- pbx/pbx_dundi.c | 89 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 55 insertions(+), 34 deletions(-) diff --git a/pbx/pbx_dundi.c b/pbx/pbx_dundi.c index 28f745753..ca13bdc76 100644 --- a/pbx/pbx_dundi.c +++ b/pbx/pbx_dundi.c @@ -1483,23 +1483,37 @@ static int handle_command_response(struct dundi_transaction *trans, struct dundi int res; int authpass=0; unsigned char *bufcpy; - struct dundi_ie_data ied; - struct dundi_ies ies; +#ifdef LOW_MEMORY + struct dundi_ie_data *ied = ast_calloc(1, sizeof(*ied)); +#else + struct dundi_ie_data _ied = { + .pos = 0, + }; + struct dundi_ie_data *ied = &_ied; +#endif + struct dundi_ies ies = { + .eidcount = 0, + }; struct dundi_peer *peer = NULL; char eid_str[20]; char eid_str2[20]; - memset(&ied, 0, sizeof(ied)); - memset(&ies, 0, sizeof(ies)); + int retval = -1; + + if (!ied) { + return -1; + } + if (datalen) { bufcpy = alloca(datalen); - if (!bufcpy) - return -1; + if (!bufcpy) { + goto return_cleanup; + } /* Make a copy for parsing */ memcpy(bufcpy, hdr->ies, datalen); ast_debug(1, "Got canonical message %d (%d), %d bytes data%s\n", cmd, hdr->oseqno, datalen, final ? " (Final)" : ""); if (dundi_parse_ies(&ies, bufcpy, datalen) < 0) { ast_log(LOG_WARNING, "Failed to parse DUNDI information elements!\n"); - return -1; + goto return_cleanup; } } switch(cmd) { @@ -1515,8 +1529,8 @@ static int handle_command_response(struct dundi_transaction *trans, struct dundi /* A dialplan or entity discover -- qualify by highest level entity */ peer = find_peer(ies.eids[0]); if (!peer) { - dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, NULL); - dundi_send(trans, resp, 0, 1, &ied); + dundi_ie_append_cause(ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, NULL); + dundi_send(trans, resp, 0, 1, ied); } else { int hasauth = 0; trans->us_eid = peer->us_eid; @@ -1533,16 +1547,16 @@ static int handle_command_response(struct dundi_transaction *trans, struct dundi } else { if (ast_strlen_zero(ies.called_number)) { /* They're not permitted to access that context */ - dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_GENERAL, "Invalid or missing number/entity"); - dundi_send(trans, resp, 0, 1, &ied); + dundi_ie_append_cause(ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_GENERAL, "Invalid or missing number/entity"); + dundi_send(trans, resp, 0, 1, ied); } else if ((cmd == DUNDI_COMMAND_DPDISCOVER) && (peer->model & DUNDI_MODEL_INBOUND) && has_permission(&peer->permit, ies.called_context)) { res = dundi_answer_query(trans, &ies, ies.called_context); if (res < 0) { /* There is no such dundi context */ - dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Unsupported DUNDI Context"); - dundi_send(trans, resp, 0, 1, &ied); + dundi_ie_append_cause(ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Unsupported DUNDI Context"); + dundi_send(trans, resp, 0, 1, ied); } } else if ((cmd = DUNDI_COMMAND_PRECACHERQ) && (peer->pcmodel & DUNDI_MODEL_INBOUND) && @@ -1550,19 +1564,19 @@ static int handle_command_response(struct dundi_transaction *trans, struct dundi res = dundi_prop_precache(trans, &ies, ies.called_context); if (res < 0) { /* There is no such dundi context */ - dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Unsupported DUNDI Context"); - dundi_send(trans, resp, 0, 1, &ied); + dundi_ie_append_cause(ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Unsupported DUNDI Context"); + dundi_send(trans, resp, 0, 1, ied); } } else { /* They're not permitted to access that context */ - dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Permission to context denied"); - dundi_send(trans, resp, 0, 1, &ied); + dundi_ie_append_cause(ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Permission to context denied"); + dundi_send(trans, resp, 0, 1, ied); } } } else { /* They're not permitted to access that context */ - dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Unencrypted responses not permitted"); - dundi_send(trans, resp, 0, 1, &ied); + dundi_ie_append_cause(ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Unencrypted responses not permitted"); + dundi_send(trans, resp, 0, 1, ied); } } break; @@ -1587,8 +1601,8 @@ static int handle_command_response(struct dundi_transaction *trans, struct dundi } if (!peer || !peer->dynamic) { - dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, NULL); - dundi_send(trans, DUNDI_COMMAND_REGRESPONSE, 0, 1, &ied); + dundi_ie_append_cause(ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, NULL); + dundi_send(trans, DUNDI_COMMAND_REGRESPONSE, 0, 1, ied); } else { int hasauth = 0; trans->us_eid = peer->us_eid; @@ -1613,8 +1627,8 @@ static int handle_command_response(struct dundi_transaction *trans, struct dundi } memcpy(&peer->addr, &trans->addr, sizeof(peer->addr)); - dundi_ie_append_short(&ied, DUNDI_IE_EXPIRATION, default_expiration); - dundi_send(trans, DUNDI_COMMAND_REGRESPONSE, 0, 1, &ied); + dundi_ie_append_short(ied, DUNDI_IE_EXPIRATION, default_expiration); + dundi_send(trans, DUNDI_COMMAND_REGRESPONSE, 0, 1, ied); if (needqual) qualify_peer(peer, 1); } @@ -1770,8 +1784,8 @@ static int handle_command_response(struct dundi_transaction *trans, struct dundi if (!hasauth) { ast_log(LOG_NOTICE, "Reponse to register not authorized!\n"); if (!final) { - dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Improper signature in answer"); - dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, &ied); + dundi_ie_append_cause(ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Improper signature in answer"); + dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, ied); } } else { ast_debug(1, "Yay, we've registered as '%s' to '%s'\n", ast_eid_to_str(eid_str, sizeof(eid_str), &trans->us_eid), @@ -1814,13 +1828,13 @@ static int handle_command_response(struct dundi_transaction *trans, struct dundi memset(&ies, 0, sizeof(ies)); dundi_parse_ies(&ies, (AST_LIST_FIRST(&trans->lasttrans))->h->ies, (AST_LIST_FIRST(&trans->lasttrans))->datalen - sizeof(struct dundi_hdr)); /* Reconstruct outgoing encrypted packet */ - memset(&ied, 0, sizeof(ied)); - dundi_ie_append_eid(&ied, DUNDI_IE_EID, &trans->us_eid); - dundi_ie_append_raw(&ied, DUNDI_IE_SHAREDKEY, peer->txenckey, 128); - dundi_ie_append_raw(&ied, DUNDI_IE_SIGNATURE, peer->txenckey + 128, 128); + memset(ied, 0, sizeof(*ied)); + dundi_ie_append_eid(ied, DUNDI_IE_EID, &trans->us_eid); + dundi_ie_append_raw(ied, DUNDI_IE_SHAREDKEY, peer->txenckey, 128); + dundi_ie_append_raw(ied, DUNDI_IE_SIGNATURE, peer->txenckey + 128, 128); if (ies.encblock) - dundi_ie_append_encdata(&ied, DUNDI_IE_ENCDATA, ies.encblock->iv, ies.encblock->encdata, ies.enclen); - dundi_send(trans, DUNDI_COMMAND_ENCRYPT, 0, (AST_LIST_FIRST(&trans->lasttrans))->h->cmdresp & 0x80, &ied); + dundi_ie_append_encdata(ied, DUNDI_IE_ENCDATA, ies.encblock->iv, ies.encblock->encdata, ies.enclen); + dundi_send(trans, DUNDI_COMMAND_ENCRYPT, 0, (AST_LIST_FIRST(&trans->lasttrans))->h->cmdresp & 0x80, ied); peer->sentfullkey = 1; } } @@ -1872,11 +1886,18 @@ static int handle_command_response(struct dundi_transaction *trans, struct dundi /* Send unknown command if we don't know it, with final flag IFF it's the first command in the dialog and only if we haven't recieved final notification */ if (!final) { - dundi_ie_append_byte(&ied, DUNDI_IE_UNKNOWN, cmd); - dundi_send(trans, DUNDI_COMMAND_UNKNOWN, 0, !hdr->oseqno, &ied); + dundi_ie_append_byte(ied, DUNDI_IE_UNKNOWN, cmd); + dundi_send(trans, DUNDI_COMMAND_UNKNOWN, 0, !hdr->oseqno, ied); } } - return 0; + + retval = 0; + +return_cleanup: +#ifdef LOW_MEMORY + ast_free(ied); +#endif + return retval; } static void destroy_packet(struct dundi_packet *pack, int needfree); -- cgit v1.2.3