diff --git a/debian/patches/series b/debian/patches/series index bf33e30c9..903522261 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -33,7 +33,6 @@ sipwise/sca-fix-pickup-when-upstream-flow.patch sipwise/sca-fix-on-hold-detection-when-upstream-flow.patch sipwise/sca-debug.patch sipwise/sca-fix-notify-after-bye.patch -sipwise/sca-fix-memleaks.patch ## backport from kamailio trunk (5.4) upstream/core-events-support-for-basic-void-core-callbacks.patch upstream/core-main-executes-callbacks-on-app-ready-and-shutdo.patch diff --git a/debian/patches/sipwise/sca-call-info-unsubscribe.patch b/debian/patches/sipwise/sca-call-info-unsubscribe.patch index cc6fe69f0..e5b3ee835 100644 --- a/debian/patches/sipwise/sca-call-info-unsubscribe.patch +++ b/debian/patches/sipwise/sca-call-info-unsubscribe.patch @@ -7,19 +7,19 @@ Subject: sca-call-info-unsubscribe 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/modules/sca/sca_subscribe.c b/src/modules/sca/sca_subscribe.c -index 6d7eb03..5a31a8e 100644 +index 14c6062..86d348d 100644 --- a/src/modules/sca/sca_subscribe.c +++ b/src/modules/sca/sca_subscribe.c -@@ -1154,6 +1154,8 @@ int ki_sca_handle_subscribe(sip_msg_t *msg, str *uri_to, str *uri_from) +@@ -1160,6 +1160,8 @@ int ki_sca_handle_subscribe(sip_msg_t *msg, str *uri_to, str *uri_from) int released = 0; int_str val; - struct to_body *tmp_to; + sca_to_body_t tmp_to; + sca_hash_slot *slot = NULL; + sca_hash_entry *ent = NULL; + memset(&tmp_to, 0, sizeof(tmp_to)); if(parse_headers(msg, HDR_EOH_F, 0) < 0) { - LM_ERR("header parsing failed: bad request\n"); -@@ -1245,12 +1247,17 @@ int ki_sca_handle_subscribe(sip_msg_t *msg, str *uri_to, str *uri_from) +@@ -1252,12 +1254,17 @@ int ki_sca_handle_subscribe(sip_msg_t *msg, str *uri_to, str *uri_from) } } @@ -39,7 +39,7 @@ index 6d7eb03..5a31a8e 100644 // this will remove the subscription if expires == 0 if(sca_subscription_update_unsafe(sca, sub, &req_sub, idx) < 0) { SCA_SUB_REPLY_ERROR(sca, 500, -@@ -1307,10 +1314,25 @@ int ki_sca_handle_subscribe(sip_msg_t *msg, str *uri_to, str *uri_from) +@@ -1314,10 +1321,25 @@ int ki_sca_handle_subscribe(sip_msg_t *msg, str *uri_to, str *uri_from) LM_INFO("sca_handle_subscribe: released %d appearances " "for subscriber %.*s\n", released, STR_FMT(&req_sub.subscriber)); @@ -65,7 +65,7 @@ index 6d7eb03..5a31a8e 100644 // in-dialog request, but we didn't find it. if(!SCA_STR_EMPTY(to_tag)) { SCA_SUB_REPLY_ERROR( -@@ -1349,6 +1371,8 @@ int ki_sca_handle_subscribe(sip_msg_t *msg, str *uri_to, str *uri_from) +@@ -1356,6 +1378,8 @@ int ki_sca_handle_subscribe(sip_msg_t *msg, str *uri_to, str *uri_from) // we got an in-dialog SUBSCRIBE with an "Expires: 0" header, // but the dialog wasn't in our table. just reply with the // subscription info we got, without saving or creating anything. diff --git a/debian/patches/sipwise/sca-debug.patch b/debian/patches/sipwise/sca-debug.patch index 377467374..09753e2c7 100644 --- a/debian/patches/sipwise/sca-debug.patch +++ b/debian/patches/sipwise/sca-debug.patch @@ -47,10 +47,10 @@ index 78ee5d8..dca2421 100644 } } diff --git a/src/modules/sca/sca_call_info.c b/src/modules/sca/sca_call_info.c -index b5b2a86..e8fccf2 100644 +index 419df8c..2eb035e 100644 --- a/src/modules/sca/sca_call_info.c +++ b/src/modules/sca/sca_call_info.c -@@ -965,6 +965,8 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg, +@@ -975,6 +975,8 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg, if(!upstream && !SCA_CALL_INFO_IS_SHARED_CALLER(call_info)) { // caller isn't SCA, no more to do. update callee in reply handler. @@ -59,7 +59,7 @@ index b5b2a86..e8fccf2 100644 rc = 1; goto done; } -@@ -982,6 +984,7 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg, +@@ -992,6 +994,7 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg, } if(sca_call_is_held(msg)) { @@ -67,7 +67,7 @@ index b5b2a86..e8fccf2 100644 state = SCA_APPEARANCE_STATE_HELD; if(call_info->state == SCA_APPEARANCE_STATE_HELD_PRIVATE) { state = SCA_APPEARANCE_STATE_HELD_PRIVATE; -@@ -990,13 +993,17 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg, +@@ -1000,13 +1003,17 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg, } } else if(!SCA_STR_EMPTY(&to->tag_value)) { // this is a reINVITE from an SCA line that put the call on hold @@ -85,7 +85,7 @@ index b5b2a86..e8fccf2 100644 } } -@@ -1169,6 +1176,8 @@ static int sca_call_info_insert_asserted_identity( +@@ -1179,6 +1186,8 @@ static int sca_call_info_insert_asserted_identity( memcpy(hdr.s + hdr.len, CRLF, CRLF_LEN); hdr.len += CRLF_LEN; @@ -94,7 +94,7 @@ index b5b2a86..e8fccf2 100644 // append the PAI header before the sdp body if(insert_new_lump_before(anchor, hdr.s, hdr.len, HDR_PAI_T) == NULL) { LM_ERR("Failed to add PAI header %.*s\n", STR_FMT(&hdr)); -@@ -1210,11 +1219,19 @@ static int sca_call_info_invite_reply_200_handler(sip_msg_t *msg, +@@ -1220,11 +1229,19 @@ static int sca_call_info_invite_reply_200_handler(sip_msg_t *msg, if(SCA_CALL_INFO_IS_SHARED_CALLEE(call_info) && (!SCA_STR_EQ(from_aor, to_aor))) { @@ -114,7 +114,7 @@ index b5b2a86..e8fccf2 100644 goto done; } -@@ -1242,6 +1259,8 @@ static int sca_call_info_invite_reply_200_handler(sip_msg_t *msg, +@@ -1252,6 +1269,8 @@ static int sca_call_info_invite_reply_200_handler(sip_msg_t *msg, &from->tag_value, NULL, slot_idx); if(app == NULL) { // no SCA line is involved with this call @@ -123,7 +123,7 @@ index b5b2a86..e8fccf2 100644 rc = 1; goto done; } -@@ -1414,6 +1433,8 @@ void sca_call_info_ack_from_handler(sip_msg_t *msg, str *from_aor, str *to_aor) +@@ -1426,6 +1445,8 @@ void sca_call_info_ack_from_handler(sip_msg_t *msg, str *from_aor, str *to_aor) sca_appearance_update_state_unsafe(app, state); // can't send NOTIFYs until we unlock the slot below } @@ -132,7 +132,7 @@ index b5b2a86..e8fccf2 100644 } done: -@@ -1564,7 +1585,11 @@ static int sca_call_info_bye_handler(sip_msg_t *msg, sca_call_info *call_info, +@@ -1593,7 +1614,11 @@ static int sca_call_info_bye_handler(sip_msg_t *msg, sca_call_info *call_info, str *tag = NULL; if(msg->first_line.type == SIP_REQUEST) { @@ -144,7 +144,7 @@ index b5b2a86..e8fccf2 100644 slot_idx = sca_uri_lock_shared_appearance(sca, from_aor); if(slot_idx < 0) { LM_ERR("sca_call_info_bye_handler: failed to acquire " -@@ -1618,6 +1643,10 @@ static int sca_call_info_bye_handler(sip_msg_t *msg, sca_call_info *call_info, +@@ -1647,6 +1672,10 @@ static int sca_call_info_bye_handler(sip_msg_t *msg, sca_call_info *call_info, goto done; } } @@ -155,7 +155,7 @@ index b5b2a86..e8fccf2 100644 } if(slot_idx >= 0) { -@@ -1673,6 +1702,7 @@ static int sca_call_info_bye_handler(sip_msg_t *msg, sca_call_info *call_info, +@@ -1702,6 +1731,7 @@ static int sca_call_info_bye_handler(sip_msg_t *msg, sca_call_info *call_info, } } } else { @@ -163,7 +163,7 @@ index b5b2a86..e8fccf2 100644 // this is just a backup to catch anything missed on the BYE request if(SCA_CALL_INFO_IS_SHARED_CALLEE(call_info)) { slot_idx = sca_hash_table_index_for_key(sca->appearances, to_aor); -@@ -2046,28 +2076,37 @@ int sca_call_info_update( +@@ -2087,28 +2117,37 @@ int sca_call_info_update( if(sca_uri_is_shared_appearance(sca, &from_aor)) { if((update_mask & SCA_CALL_INFO_SHARED_CALLER)) { call_info.ua_shared |= SCA_CALL_INFO_SHARED_CALLER; diff --git a/debian/patches/sipwise/sca-fallback-if-no-contact.patch b/debian/patches/sipwise/sca-fallback-if-no-contact.patch index e0d9c5377..bf64c2f66 100644 --- a/debian/patches/sipwise/sca-fallback-if-no-contact.patch +++ b/debian/patches/sipwise/sca-fallback-if-no-contact.patch @@ -7,10 +7,10 @@ Subject: sca-fallback-if-no-contact 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/modules/sca/sca_call_info.c b/src/modules/sca/sca_call_info.c -index 867421b..a173294 100644 +index 0617cea..d83fe48 100644 --- a/src/modules/sca/sca_call_info.c +++ b/src/modules/sca/sca_call_info.c -@@ -1944,9 +1944,6 @@ int sca_call_info_update( +@@ -1978,9 +1978,6 @@ int sca_call_info_update( rc = -1; goto done; } @@ -20,7 +20,7 @@ index 867421b..a173294 100644 } // reset rc to -1 so we don't end up returning 0 to the script rc = -1; -@@ -1992,6 +1989,13 @@ int sca_call_info_update( +@@ -2027,6 +2024,13 @@ int sca_call_info_update( LM_DBG("to_aor[%.*s] from_aor[%.*s]\n", STR_FMT(&to_aor), STR_FMT(&from_aor)); diff --git a/debian/patches/sipwise/sca-fix-memleaks.patch b/debian/patches/sipwise/sca-fix-memleaks.patch deleted file mode 100644 index 791317a3a..000000000 --- a/debian/patches/sipwise/sca-fix-memleaks.patch +++ /dev/null @@ -1,30 +0,0 @@ -From: Sipwise Development Team -Date: Thu, 26 Mar 2020 10:06:46 +0100 -Subject: sca-fix-memleaks - ---- - src/modules/sca/sca_util.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/modules/sca/sca_util.c b/src/modules/sca/sca_util.c -index e1ef561..9fa64ca 100644 ---- a/src/modules/sca/sca_util.c -+++ b/src/modules/sca/sca_util.c -@@ -180,6 +180,8 @@ int sca_get_msg_from_header(sip_msg_t *msg, struct to_body **from) - } else { - LM_DBG("using $avp(%.*s)[%.*s] as from uri\n", STR_FMT(&from_uri_avp.s), - STR_FMT(&uri)); -+ free_to_params(&sf); -+ memset(&sf, 0, sizeof(sf)); - if(sca_parse_uri(&sf, &uri) < 0) - return -1; - *from = &sf; -@@ -224,6 +226,8 @@ int sca_get_msg_to_header(sip_msg_t *msg, struct to_body **to) - } else { - LM_DBG("using $avp(%.*s)[%.*s] as to uri\n", STR_FMT(&to_uri_avp.s), - STR_FMT(&uri)); -+ free_to_params(&parsed_to); -+ memset(&parsed_to, 0, sizeof(parsed_to)); - if(sca_parse_uri(&parsed_to, &uri) < 0) - return -1; - *to = &parsed_to; diff --git a/debian/patches/sipwise/sca-fix-notify-after-bye.patch b/debian/patches/sipwise/sca-fix-notify-after-bye.patch index 7990aa200..b6cfa64cf 100644 --- a/debian/patches/sipwise/sca-fix-notify-after-bye.patch +++ b/debian/patches/sipwise/sca-fix-notify-after-bye.patch @@ -7,7 +7,7 @@ Subject: sca-fix-notify-after-bye 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/sca/sca_call_info.c b/src/modules/sca/sca_call_info.c -index e8fccf2..42710a1 100644 +index 2eb035e..d01ab86 100644 --- a/src/modules/sca/sca_call_info.c +++ b/src/modules/sca/sca_call_info.c @@ -714,7 +714,7 @@ static int sca_call_info_uri_update(str *aor, sca_call_info *call_info, diff --git a/debian/patches/sipwise/sca-fix-on-hold-detection-when-upstream-flow.patch b/debian/patches/sipwise/sca-fix-on-hold-detection-when-upstream-flow.patch index ccd9d5b9b..8a0ff3c17 100644 --- a/debian/patches/sipwise/sca-fix-on-hold-detection-when-upstream-flow.patch +++ b/debian/patches/sipwise/sca-fix-on-hold-detection-when-upstream-flow.patch @@ -7,10 +7,10 @@ Subject: sca-fix-on-hold-detection-when-upstream-flow 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modules/sca/sca_call_info.c b/src/modules/sca/sca_call_info.c -index 0a72427..b5b2a86 100644 +index ed43fe2..419df8c 100644 --- a/src/modules/sca/sca_call_info.c +++ b/src/modules/sca/sca_call_info.c -@@ -938,11 +938,13 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg, +@@ -948,11 +948,13 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg, int state = SCA_APPEARANCE_STATE_UNKNOWN; int rc = -1; str *target_aor = from_aor; @@ -24,7 +24,7 @@ index 0a72427..b5b2a86 100644 } LM_DBG("For From-AOR %.*s To-AOR: %.*s: From: <%.*s> To: <%.*s> " -@@ -961,7 +963,7 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg, +@@ -971,7 +973,7 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg, goto done; } diff --git a/debian/patches/sipwise/sca-fix-pickup-when-upstream-flow.patch b/debian/patches/sipwise/sca-fix-pickup-when-upstream-flow.patch index c4df52228..60945fb75 100644 --- a/debian/patches/sipwise/sca-fix-pickup-when-upstream-flow.patch +++ b/debian/patches/sipwise/sca-fix-pickup-when-upstream-flow.patch @@ -7,10 +7,10 @@ Subject: sca-fix-pickup-when-upstream-flow 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/src/modules/sca/sca_call_info.c b/src/modules/sca/sca_call_info.c -index 00a4c0e..0a72427 100644 +index 8734d3a..ed43fe2 100644 --- a/src/modules/sca/sca_call_info.c +++ b/src/modules/sca/sca_call_info.c -@@ -937,6 +937,13 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg, +@@ -947,6 +947,13 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg, str state_str = STR_NULL; int state = SCA_APPEARANCE_STATE_UNKNOWN; int rc = -1; @@ -24,7 +24,7 @@ index 00a4c0e..0a72427 100644 LM_DBG("For From-AOR %.*s To-AOR: %.*s: From: <%.*s> To: <%.*s> " "Contact: <%.*s> Call-Info: appearance-index=%d\n", -@@ -950,7 +957,7 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg, +@@ -960,7 +967,7 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg, < 0) { LM_ERR("sca_call_info_invite_request_handler: failed to register " "callback for INVITE %.*s ACK\n", @@ -33,7 +33,7 @@ index 00a4c0e..0a72427 100644 goto done; } -@@ -968,7 +975,7 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg, +@@ -978,7 +985,7 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg, < 0) { LM_ERR("sca_call_info_invite_request_handler: failed to register " "callback for INVITE %.*s ACK\n", @@ -42,7 +42,7 @@ index 00a4c0e..0a72427 100644 goto done; } -@@ -1001,16 +1008,16 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg, +@@ -1011,16 +1018,16 @@ int sca_call_info_invite_request_handler(sip_msg_t *msg, } if(sca_appearance_update_index( @@ -63,32 +63,32 @@ index 00a4c0e..0a72427 100644 goto done; } -@@ -1356,6 +1363,7 @@ void sca_call_info_ack_from_handler(sip_msg_t *msg, str *from_aor, str *to_aor) +@@ -1365,6 +1372,7 @@ void sca_call_info_ack_from_handler(sip_msg_t *msg, str *from_aor, str *to_aor) str *tag; int slot_idx = -1; int state = SCA_APPEARANCE_STATE_IDLE; -+ str *target_aor; ++ str *target_aor = NULL; - if(sca_get_msg_from_header(msg, &from) < 0) { - LM_ERR("sca_call_info_ack_cb: failed to get From-header\n"); -@@ -1366,19 +1374,24 @@ void sca_call_info_ack_from_handler(sip_msg_t *msg, str *from_aor, str *to_aor) - return; + memset(&from, 0, sizeof(from)); + memset(&to, 0, sizeof(to)); +@@ -1378,19 +1386,24 @@ void sca_call_info_ack_from_handler(sip_msg_t *msg, str *from_aor, str *to_aor) + goto done; } - if(sca_uri_lock_if_shared_appearance(sca, from_aor, &slot_idx)) { - if(sca->rr_api->is_direction(msg, RR_FLOW_UPSTREAM) == 0) { - LM_DBG("upstream direction detected\n"); -- tag = &to->tag_value; +- tag = &to.hdr->tag_value; - } else { -- tag = &from->tag_value; +- tag = &from.hdr->tag_value; - } + if(sca->rr_api->is_direction(msg, RR_FLOW_UPSTREAM) == 0) { + LM_DBG("upstream direction detected\n"); + target_aor = to_aor; -+ tag = &to->tag_value; ++ tag = &to.hdr->tag_value; + } else { + target_aor = from_aor; -+ tag = &from->tag_value; ++ tag = &from.hdr->tag_value; + } + + LM_DBG("target_aor[%.*s]\n", STR_FMT(target_aor)); @@ -105,7 +105,7 @@ index 00a4c0e..0a72427 100644 STR_FMT(tag)); goto done; } -@@ -1406,10 +1419,10 @@ done: +@@ -1418,10 +1431,10 @@ done: sca_hash_table_unlock_index(sca->appearances, slot_idx); if(state != SCA_APPEARANCE_STATE_IDLE) { diff --git a/debian/patches/sipwise/sca-line-seize.patch b/debian/patches/sipwise/sca-line-seize.patch index 9480fd013..c4246fcb8 100644 --- a/debian/patches/sipwise/sca-line-seize.patch +++ b/debian/patches/sipwise/sca-line-seize.patch @@ -3,16 +3,17 @@ Date: Thu, 26 Mar 2020 10:06:46 +0100 Subject: sca-line-seize --- - src/modules/sca/sca.c | 107 ++++++++++++++++++++++++++- + src/modules/sca/sca.c | 107 +++++++++++++++++++++- src/modules/sca/sca.h | 6 ++ src/modules/sca/sca_appearance.h | 2 +- - src/modules/sca/sca_call_info.c | 78 +++++++++----------- + src/modules/sca/sca_call_info.c | 188 ++++++++++++++++++++++----------------- src/modules/sca/sca_call_info.h | 6 +- src/modules/sca/sca_dialog.h | 2 +- - src/modules/sca/sca_subscribe.c | 61 ++++++++------- + src/modules/sca/sca_subscribe.c | 96 ++++++++++++-------- src/modules/sca/sca_subscribe.h | 6 +- - src/modules/sca/sca_util.c | 155 +++++++++++++++++++++++---------------- - 9 files changed, 279 insertions(+), 144 deletions(-) + src/modules/sca/sca_util.c | 177 ++++++++++++++++++++++-------------- + src/modules/sca/sca_util.h | 18 +++- + 10 files changed, 406 insertions(+), 202 deletions(-) diff --git a/src/modules/sca/sca.c b/src/modules/sca/sca.c index 07dac39..c2347bb 100644 @@ -210,10 +211,264 @@ index bd94e14..6ce3112 100644 enum { diff --git a/src/modules/sca/sca_call_info.c b/src/modules/sca/sca_call_info.c -index c443f23..867421b 100644 +index c443f23..0617cea 100644 --- a/src/modules/sca/sca_call_info.c +++ b/src/modules/sca/sca_call_info.c -@@ -1851,11 +1851,11 @@ int sca_call_info_update( +@@ -842,44 +842,46 @@ static int sca_call_info_is_line_seize_reinvite(sip_msg_t *msg, + */ + static void sca_call_info_local_error_reply_handler(sip_msg_t *msg, int status) + { +- struct to_body *from; +- struct to_body *to; ++ sca_to_body_t from, to; + sca_appearance *app; + str aor = STR_NULL; + str contact_uri = STR_NULL; + int rc; + ++ memset(&from, 0, sizeof(from)); ++ memset(&to, 0, sizeof(to)); ++ + if(sca_get_msg_from_header(msg, &from) < 0) { + LM_ERR("sca_call_info_sl_reply_cb: failed to get From header from " + "request before stateless reply with %d\n", + status); +- return; ++ goto done; + } +- if(sca_uri_extract_aor(&from->uri, &aor) < 0) { ++ if(sca_uri_extract_aor(&from.hdr->uri, &aor) < 0) { + LM_ERR("sca_call_info_sl_reply_cb: failed to extract AoR " + "from URI %.*s\n", +- STR_FMT(&from->uri)); +- return; ++ STR_FMT(&from.hdr->uri)); ++ goto done; + } + + if(!sca_uri_is_shared_appearance(sca, &aor)) { + // LM_DBG("sca_call_info_sl_reply_cb: ignoring non-shared appearance " + // "%.*s\n", STR_FMT(&aor)); +- return; ++ goto done; + } + + if(sca_get_msg_contact_uri(msg, &contact_uri) < 0) { + LM_ERR("sca_call_info_sl_reply_cb: failed to get Contact from " + "request before stateless reply with %d\n", + status); +- return; ++ goto done; + } + + if(sca_get_msg_to_header(msg, &to) < 0) { + LM_ERR("sca_call_info_sl_reply_cb: failed to get To header from " + "request before stateless reply with %d\n", + status); +- return; ++ goto done; + } + + // two typical cases to handle. in the first case, we haven't dropped +@@ -901,7 +903,7 @@ static void sca_call_info_local_error_reply_handler(sip_msg_t *msg, int status) + } else if(rc == 0) { + // no line-seize subscription found + app = sca_appearance_unlink_by_tags(sca, &aor, &msg->callid->body, +- &from->tag_value, &to->tag_value); ++ &from.hdr->tag_value, &to.hdr->tag_value); + if(app) { + sca_appearance_free(app); + if(sca_notify_call_info_subscribers(sca, &aor) < 0) { +@@ -911,6 +913,14 @@ static void sca_call_info_local_error_reply_handler(sip_msg_t *msg, int status) + } + } + } ++ ++done: ++ if(from.flags & SCA_UTIL_FLAG_TO_BODY_ALLOC) { ++ free_to(from.hdr); ++ } ++ if(to.flags & SCA_UTIL_FLAG_TO_BODY_ALLOC) { ++ free_to(to.hdr); ++ } + } + + void sca_call_info_response_ready_cb( +@@ -1351,28 +1361,30 @@ static int sca_call_info_invite_reply_error_handler(sip_msg_t *msg, + void sca_call_info_ack_from_handler(sip_msg_t *msg, str *from_aor, str *to_aor) + { + sca_appearance *app; +- struct to_body *from; +- struct to_body *to; ++ sca_to_body_t from, to; + int slot_idx = -1; + int state = SCA_APPEARANCE_STATE_IDLE; + ++ memset(&from, 0, sizeof(from)); ++ memset(&to, 0, sizeof(to)); ++ + if(sca_get_msg_from_header(msg, &from) < 0) { + LM_ERR("sca_call_info_ack_cb: failed to get From-header\n"); +- return; ++ goto done; + } + if(sca_get_msg_to_header(msg, &to) < 0) { + LM_ERR("sca_call_info_ack_cb: failed to get To-header\n"); +- return; ++ goto done; + } + + if(sca_uri_lock_if_shared_appearance(sca, from_aor, &slot_idx)) { + app = sca_appearance_for_tags_unsafe(sca, from_aor, &msg->callid->body, +- &from->tag_value, NULL, slot_idx); ++ &from.hdr->tag_value, NULL, slot_idx); + if(app == NULL) { + LM_ERR("sca_call_info_ack_cb: No appearance for %.*s matching " + "call-id <%.*s> and from-tag <%.*s>\n", + STR_FMT(from_aor), STR_FMT(&msg->callid->body), +- STR_FMT(&from->tag_value)); ++ STR_FMT(&from.hdr->tag_value)); + goto done; + } + +@@ -1406,17 +1418,25 @@ done: + } + } + } ++ if(from.flags & SCA_UTIL_FLAG_TO_BODY_ALLOC) { ++ free_to(from.hdr); ++ } ++ if(to.flags & SCA_UTIL_FLAG_TO_BODY_ALLOC) { ++ free_to(to.hdr); ++ } + } + + /* XXX needs extract routines */ + void sca_call_info_ack_cb(struct cell *t, int type, struct tmcb_params *params) + { +- struct to_body *to; ++ sca_to_body_t to; + sca_appearance *app = NULL; + str from_aor = STR_NULL; + str to_aor = STR_NULL; + int slot_idx = -1; + ++ memset(&to, 0, sizeof(to)); ++ + if(!(type & TMCB_E2EACK_IN)) { + return; + } +@@ -1429,9 +1449,9 @@ void sca_call_info_ack_cb(struct cell *t, int type, struct tmcb_params *params) + LM_ERR("sca_call_info_ack_cb: failed to get To-header\n"); + goto done; + } +- if(sca_uri_extract_aor(&to->uri, &to_aor) < 0) { ++ if(sca_uri_extract_aor(&to.hdr->uri, &to_aor) < 0) { + LM_ERR("sca_call_info_ack_cb: failed to extract To AoR from %.*s\n", +- STR_FMT(&to->uri)); ++ STR_FMT(&to.hdr->uri)); + goto done; + } + +@@ -1445,7 +1465,7 @@ void sca_call_info_ack_cb(struct cell *t, int type, struct tmcb_params *params) + + // on ACK, ensure SCA callee state is promoted to ACTIVE. + app = sca_appearance_for_tags_unsafe(sca, &to_aor, +- ¶ms->req->callid->body, &to->tag_value, NULL, slot_idx); ++ ¶ms->req->callid->body, &to.hdr->tag_value, NULL, slot_idx); + if(app && app->state == SCA_APPEARANCE_STATE_ACTIVE_PENDING) { + LM_DBG("promoting %.*s appearance-index %d to active\n", + STR_FMT(&to_aor), app->index); +@@ -1467,6 +1487,9 @@ done: + if(from_aor.s != NULL) { + pkg_free(from_aor.s); + } ++ if(to.flags & SCA_UTIL_FLAG_TO_BODY_ALLOC) { ++ free_to(to.hdr); ++ } + } + + static int sca_call_info_invite_handler(sip_msg_t *msg, +@@ -1736,11 +1759,13 @@ void sca_call_info_sl_reply_cb(void *cb_arg) + { + sl_cbp_t *slcbp = (sl_cbp_t *)cb_arg; + sip_msg_t *msg; +- struct to_body *from; +- struct to_body *to; ++ sca_to_body_t from, to; + str aor = STR_NULL; + str contact_uri = STR_NULL; + ++ memset(&from, 0, sizeof(from)); ++ memset(&to, 0, sizeof(to)); ++ + if(slcbp == NULL) { + return; + } +@@ -1768,31 +1793,31 @@ void sca_call_info_sl_reply_cb(void *cb_arg) + slcbp->code, STR_FMT(slcbp->reason)); + return; + } +- if(sca_uri_extract_aor(&from->uri, &aor) < 0) { ++ if(sca_uri_extract_aor(&from.hdr->uri, &aor) < 0) { + LM_ERR("sca_call_info_sl_reply_cb: failed to extract AoR " + "from URI %.*s\n", +- STR_FMT(&from->uri)); +- return; ++ STR_FMT(&from.hdr->uri)); ++ goto done; + } + + if(!sca_uri_is_shared_appearance(sca, &aor)) { + // LM_DBG("sca_call_info_sl_reply_cb: ignoring non-shared appearance " + // "%.*s", STR_FMT(&aor)); +- return; ++ goto done; + } + + if(sca_get_msg_contact_uri(msg, &contact_uri) < 0) { + LM_ERR("sca_call_info_sl_reply_cb: failed to get Contact from " + "request before stateless reply with %d %.*s\n", + slcbp->code, STR_FMT(slcbp->reason)); +- return; ++ goto done; + } + + if(sca_get_msg_to_header(msg, &to) < 0) { + LM_ERR("sca_call_info_sl_reply_cb: failed to get To header from " + "request before stateless reply with %d %.*s\n", + slcbp->code, STR_FMT(slcbp->reason)); +- return; ++ goto done; + } + + if(sca_subscription_terminate(sca, &aor, SCA_EVENT_TYPE_LINE_SEIZE, +@@ -1802,7 +1827,15 @@ void sca_call_info_sl_reply_cb(void *cb_arg) + LM_ERR("sca_call_info_sl_reply_cb: failed to terminate " + "line-seize subscription for %.*s\n", + STR_FMT(&contact_uri)); +- return; ++ goto done; ++ } ++ ++done: ++ if(from.flags & SCA_UTIL_FLAG_TO_BODY_ALLOC) { ++ free_to(from.hdr); ++ } ++ if(to.flags & SCA_UTIL_FLAG_TO_BODY_ALLOC) { ++ free_to(to.hdr); + } + } + +@@ -1844,20 +1877,21 @@ int sca_call_info_update( + { + sca_call_info call_info; + hdr_field_t *call_info_hdr; +- struct to_body *from; +- struct to_body *to; ++ sca_to_body_t from, to; + sip_uri_t c_uri; + str from_aor = STR_NULL; str to_aor = STR_NULL; str contact_uri = STR_NULL; int aor_flags = SCA_CALL_INFO_UPDATE_FLAG_DEFAULT; @@ -225,8 +480,12 @@ index c443f23..867421b 100644 + int_str val; method = sca_get_msg_method(msg); ++ memset(&from, 0, sizeof(from)); ++ memset(&to, 0, sizeof(to)); -@@ -1868,7 +1868,7 @@ int sca_call_info_update( + n_dispatch = sizeof(call_info_dispatch) / sizeof(call_info_dispatch[0]); + for(i = 0; i < n_dispatch; i++) { +@@ -1868,7 +1902,7 @@ int sca_call_info_update( if(i >= n_dispatch) { if(msg->cseq == NULL && ((parse_headers(msg, HDR_CSEQ_F, 0) == -1) @@ -235,7 +494,7 @@ index c443f23..867421b 100644 LM_ERR("no CSEQ header\n"); return (1); } -@@ -1900,6 +1900,9 @@ int sca_call_info_update( +@@ -1900,6 +1934,9 @@ int sca_call_info_update( } } @@ -245,7 +504,7 @@ index c443f23..867421b 100644 memset(&call_info, 0, sizeof(sca_call_info)); call_info_hdr = get_hdr(msg, HDR_CALLINFO_T); if(!SCA_HEADER_EMPTY(call_info_hdr)) { -@@ -1912,34 +1915,22 @@ int sca_call_info_update( +@@ -1912,34 +1949,22 @@ int sca_call_info_update( } if(uri_from != NULL) { @@ -291,7 +550,7 @@ index c443f23..867421b 100644 LM_ERR("Bad To header\n"); goto done; } -@@ -1967,27 +1958,34 @@ int sca_call_info_update( +@@ -1967,27 +1992,35 @@ int sca_call_info_update( goto done; } aor_flags |= SCA_CALL_INFO_UPDATE_FLAG_FROM_ALLOC; @@ -300,43 +559,61 @@ index c443f23..867421b 100644 - if(sca_uri_extract_aor(&to->uri, &to_aor) < 0) { - LM_ERR("Failed to extract AoR from To URI %.*s\n", - STR_FMT(&to->uri)); -- goto done; -- } -- } -- } else { -- if(uri_from == NULL) { + } else { - if(sca_uri_extract_aor(&from->uri, &from_aor) < 0) { - LM_ERR("Failed to extract AoR from From URI %.*s\n", - STR_FMT(&from->uri)); ++ if(sca_uri_extract_aor(&from.hdr->uri, &from_aor) < 0) { ++ LM_ERR("Failed to extract AoR from From URI %.*s\n", ++ STR_FMT(&from.hdr->uri)); goto done; } } -+ if(sca_uri_extract_aor(&to->uri, &to_aor) < 0) { -+ LM_ERR("Failed to extract AoR from To URI %.*s", STR_FMT(&to->uri)); ++ if(sca_uri_extract_aor(&to.hdr->uri, &to_aor) < 0) { ++ LM_ERR("Failed to extract AoR from To URI %.*s", ++ STR_FMT(&to.hdr->uri)); + goto done; + } -+ } else { -+ if(sca_uri_extract_aor(&from->uri, &from_aor) < 0) { + } else { +- if(uri_from == NULL) { +- if(sca_uri_extract_aor(&from->uri, &from_aor) < 0) { +- LM_ERR("Failed to extract AoR from From URI %.*s\n", +- STR_FMT(&from->uri)); +- goto done; +- } ++ if(sca_uri_extract_aor(&from.hdr->uri, &from_aor) < 0) { + LM_ERR("Failed to extract AoR from From URI %.*s", -+ STR_FMT(&from->uri)); ++ STR_FMT(&from.hdr->uri)); + goto done; -+ } + } if(uri_to == NULL) { if(sca_create_canonical_aor(msg, &to_aor) < 0) { goto done; } aor_flags |= SCA_CALL_INFO_UPDATE_FLAG_TO_ALLOC; + } else { -+ if(sca_uri_extract_aor(&to->uri, &to_aor) < 0) { ++ if(sca_uri_extract_aor(&to.hdr->uri, &to_aor) < 0) { + LM_ERR("Failed to extract AoR from To URI %.*s", -+ STR_FMT(&to->uri)); ++ STR_FMT(&to.hdr->uri)); + goto done; + } } } -@@ -2058,16 +2056,6 @@ done: +@@ -2037,11 +2070,11 @@ int sca_call_info_update( + + LM_DBG("Calling Dispatch Id: %d handler with From-AOR: %.*s To-AOR: %.*s " + "From-URI: <%.*s> To-URI: <%.*s> Contact-URI: <%.*s>\n", +- i, STR_FMT(&from_aor), STR_FMT(&to_aor), STR_FMT(&from->uri), +- STR_FMT(&to->uri), STR_FMT(&contact_uri)); ++ i, STR_FMT(&from_aor), STR_FMT(&to_aor), STR_FMT(&from.hdr->uri), ++ STR_FMT(&to.hdr->uri), STR_FMT(&contact_uri)); + +- rc = call_info_dispatch[i].handler( +- msg, &call_info, from, to, &from_aor, &to_aor, &contact_uri); ++ rc = call_info_dispatch[i].handler(msg, &call_info, from.hdr, to.hdr, ++ &from_aor, &to_aor, &contact_uri); + if(rc < 0) { + LM_ERR("Failed to update Call-Info state for %.*s\n", + STR_FMT(&contact_uri)); +@@ -2058,16 +2091,11 @@ done: pkg_free(to_aor.s); } } @@ -344,13 +621,17 @@ index c443f23..867421b 100644 - if(from != NULL) { - free_to(from); - } -- } ++ if(from.flags & SCA_UTIL_FLAG_TO_BODY_ALLOC) { ++ free_to(from.hdr); + } - if((to_body_flags & SCA_CALL_INFO_UPDATE_FLAG_TO_ALLOC)) { - if(to != NULL) { - free_to(to); - } -- } - ++ if(to.flags & SCA_UTIL_FLAG_TO_BODY_ALLOC) { ++ free_to(to.hdr); + } +- return (rc); } diff --git a/src/modules/sca/sca_call_info.h b/src/modules/sca/sca_call_info.h @@ -392,7 +673,7 @@ index d308954..dee234c 100644 int sca_dialog_build_from_tags(sca_dialog *, int, str *, str *, str *); int sca_dialog_create_replaces_header(sca_dialog *, str *); diff --git a/src/modules/sca/sca_subscribe.c b/src/modules/sca/sca_subscribe.c -index dc33f00..6d7eb03 100644 +index dc33f00..14c6062 100644 --- a/src/modules/sca/sca_subscribe.c +++ b/src/modules/sca/sca_subscribe.c @@ -844,8 +844,8 @@ static int sca_subscription_update_unsafe(sca_mod *scam, @@ -406,7 +687,29 @@ index dc33f00..6d7eb03 100644 dlg_id_tmp = (char *)shm_malloc(len); if(dlg_id_tmp == NULL) { -@@ -1023,10 +1023,6 @@ int sca_subscription_from_request(sca_mod *scam, sip_msg_t *msg, int event_type, +@@ -986,17 +986,19 @@ int sca_subscription_delete_subscriber_for_event( + int sca_subscription_from_request(sca_mod *scam, sip_msg_t *msg, int event_type, + sca_subscription *req_sub) + { +- struct to_body tmp_to = {0}; +- struct to_body *to, *from; ++ sca_to_body_t to, from; + str contact_uri; + str to_tag = STR_NULL; + unsigned int expires = 0, max_expires; + unsigned int cseq; + str *ruri = NULL; ++ int rc = 1; + + assert(req_sub != NULL); + + memset(req_sub, 0, sizeof(sca_subscription)); ++ memset(&from, 0, sizeof(from)); ++ memset(&to, 0, sizeof(to)); + + // parse required info first + if(!SCA_HEADER_EMPTY(msg->expires)) { +@@ -1023,10 +1025,6 @@ int sca_subscription_from_request(sca_mod *scam, sip_msg_t *msg, int event_type, expires = max_expires; } @@ -417,7 +720,7 @@ index dc33f00..6d7eb03 100644 if(SCA_HEADER_EMPTY(msg->callid)) { LM_ERR("Empty Call-ID header\n"); goto error; -@@ -1048,30 +1044,18 @@ int sca_subscription_from_request(sca_mod *scam, sip_msg_t *msg, int event_type, +@@ -1048,30 +1046,18 @@ int sca_subscription_from_request(sca_mod *scam, sip_msg_t *msg, int event_type, goto error; } @@ -431,7 +734,8 @@ index dc33f00..6d7eb03 100644 goto error; } - from = (struct to_body *)msg->from->parsed; - if(SCA_STR_EMPTY(&from->tag_value)) { +- if(SCA_STR_EMPTY(&from->tag_value)) { ++ if(SCA_STR_EMPTY(&from.hdr->tag_value)) { LM_ERR("No from-tag in From header\n"); goto error; } @@ -452,8 +756,60 @@ index dc33f00..6d7eb03 100644 } if(parse_sip_msg_uri(msg) < 0) { -@@ -1153,7 +1137,7 @@ error: - return (-1); +@@ -1080,7 +1066,7 @@ int sca_subscription_from_request(sca_mod *scam, sip_msg_t *msg, int event_type, + } + ruri = GET_RURI(msg); + +- to_tag = to->tag_value; ++ to_tag = to.hdr->tag_value; + if(to_tag.s == NULL) { + // XXX need hook to detect when we have a subscription and the + // subscriber sends an out-of-dialog SUBSCRIBE, which indicates the +@@ -1106,7 +1092,7 @@ int sca_subscription_from_request(sca_mod *scam, sip_msg_t *msg, int event_type, + } + } else { + /* we are in-dialog */ +- req_sub->target_aor = to->uri; ++ req_sub->target_aor = to.hdr->uri; + } + + req_sub->subscriber = contact_uri; +@@ -1124,7 +1110,7 @@ int sca_subscription_from_request(sca_mod *scam, sip_msg_t *msg, int event_type, + req_sub->dialog.id.s = NULL; + req_sub->dialog.id.len = 0; + req_sub->dialog.call_id = msg->callid->body; +- req_sub->dialog.from_tag = from->tag_value; ++ req_sub->dialog.from_tag = from.hdr->tag_value; + + req_sub->dialog.to_tag.s = pkg_malloc(to_tag.len); + if(req_sub->dialog.to_tag.s == NULL) { +@@ -1138,22 +1124,26 @@ int sca_subscription_from_request(sca_mod *scam, sip_msg_t *msg, int event_type, + req_sub->dialog.notify_cseq = 0; + req_sub->server_id = server_id; + +- free_to_params(&tmp_to); +- +- return (1); ++ goto done; + + error: +- free_to_params(&tmp_to); +- ++ rc = -1; + if(!SCA_STR_EMPTY(&req_sub->rr)) { + pkg_free(req_sub->rr.s); + req_sub->rr.s = NULL; + } ++done: ++ if(from.flags & SCA_UTIL_FLAG_TO_BODY_ALLOC) { ++ free_to(from.hdr); ++ } ++ if(to.flags & SCA_UTIL_FLAG_TO_BODY_ALLOC) { ++ free_to(to.hdr); ++ } + +- return (-1); ++ return rc; } -int ki_sca_handle_subscribe(sip_msg_t *msg) @@ -461,16 +817,18 @@ index dc33f00..6d7eb03 100644 { sca_subscription req_sub; sca_subscription *sub = NULL; -@@ -1168,6 +1152,8 @@ int ki_sca_handle_subscribe(sip_msg_t *msg) +@@ -1168,7 +1158,10 @@ int ki_sca_handle_subscribe(sip_msg_t *msg) int idx = -1; int rc = -1; int released = 0; + int_str val; -+ struct to_body *tmp_to; ++ sca_to_body_t tmp_to; ++ memset(&tmp_to, 0, sizeof(tmp_to)); if(parse_headers(msg, HDR_EOH_F, 0) < 0) { LM_ERR("header parsing failed: bad request\n"); -@@ -1192,6 +1178,21 @@ int ki_sca_handle_subscribe(sip_msg_t *msg) + SCA_SUB_REPLY_ERROR(sca, 400, "Bad Request", msg); +@@ -1192,6 +1185,21 @@ int ki_sca_handle_subscribe(sip_msg_t *msg) return (-1); } @@ -492,7 +850,7 @@ index dc33f00..6d7eb03 100644 if(sca_subscription_from_request(sca, msg, event_type, &req_sub) < 0) { SCA_SUB_REPLY_ERROR( sca, 400, "Bad Shared Call Appearance Request", msg); -@@ -1207,7 +1208,15 @@ int ki_sca_handle_subscribe(sip_msg_t *msg) +@@ -1207,7 +1215,15 @@ int ki_sca_handle_subscribe(sip_msg_t *msg) sca_subscription_print(&req_sub); // check to see if the message has a to-tag @@ -502,14 +860,21 @@ index dc33f00..6d7eb03 100644 + LM_ERR("Bad To header"); + return (-1); + } -+ to_tag = &(tmp_to->tag_value); ++ to_tag = &(tmp_to.hdr->tag_value); + } else { + to_tag = &(get_to(msg)->tag_value); + } // XXX should lock starting here and use unsafe methods below? -@@ -1391,9 +1400,9 @@ done: +@@ -1387,13 +1403,15 @@ done: + if(req_sub.rr.s != NULL) { + pkg_free(req_sub.rr.s); + } +- ++ if(tmp_to.flags & SCA_UTIL_FLAG_TO_BODY_ALLOC) { ++ free_to(tmp_to.hdr); ++ } return (rc); } @@ -552,10 +917,10 @@ index e27883e..44f93b7 100644 #endif // SCA_SUBSCRIBE_H diff --git a/src/modules/sca/sca_util.c b/src/modules/sca/sca_util.c -index 4ab4c6f..e1ef561 100644 +index 4ab4c6f..a102af4 100644 --- a/src/modules/sca/sca_util.c +++ b/src/modules/sca/sca_util.c -@@ -112,94 +112,123 @@ int sca_get_msg_cseq_method(sip_msg_t *msg) +@@ -112,94 +112,129 @@ int sca_get_msg_cseq_method(sip_msg_t *msg) return (get_cseq(msg)->method_id); } @@ -616,17 +981,15 @@ index 4ab4c6f..e1ef561 100644 } -int sca_get_msg_to_header(sip_msg_t *msg, struct to_body **to) -+int sca_get_msg_from_header(sip_msg_t *msg, struct to_body **from) ++int sca_get_msg_from_header(sip_msg_t *msg, sca_to_body_t *from) { - struct to_body parsed_to; - struct to_body *t = NULL; -+ struct to_body *f; -+ static struct to_body sf; -+ str uri = STR_NULL; - +- - assert(msg != NULL); - assert(to != NULL); -+ assert(from != NULL); ++ struct to_body *f; ++ str uri = STR_NULL; - if(SCA_HEADER_EMPTY(msg->to)) { - LM_ERR("Empty To header\n"); @@ -639,6 +1002,8 @@ index 4ab4c6f..e1ef561 100644 - &parsed_to); - if(parsed_to.error != PARSE_OK) { - LM_ERR("Bad To header\n"); ++ assert(from != NULL); ++ memset(from, 0, sizeof(sca_to_body_t)); + if(sca_get_avp_value(from_uri_avp_type, from_uri_avp, &uri) < 0) { + assert(msg != NULL); + if(SCA_HEADER_EMPTY(msg->from)) { @@ -649,6 +1014,7 @@ index 4ab4c6f..e1ef561 100644 + LM_ERR("Bad From header\n"); + return (-1); + } ++ from->flags = SCA_UTIL_FLAG_TO_BODY_MSG; + f = get_from(msg); + if(SCA_STR_EMPTY(&f->tag_value)) { + LM_ERR("Bad From header: no tag parameter\n"); @@ -661,23 +1027,27 @@ index 4ab4c6f..e1ef561 100644 - if(parse_uri(t->uri.s, t->uri.len, GET_TO_PURI(msg)) < 0) { - LM_ERR("Failed to parse To URI %.*s\n", STR_FMT(&t->uri)); - return (-1); -- } + // ensure the URI is parsed for future use + if(parse_uri(f->uri.s, f->uri.len, GET_FROM_PURI(msg)) < 0) { + LM_ERR("Failed to parse From URI %.*s\n", STR_FMT(&f->uri)); + return (-1); + } - -- *to = t; -+ *from = f; ++ from->hdr = f; + } else { + LM_DBG("using $avp(%.*s)[%.*s] as from uri\n", STR_FMT(&from_uri_avp.s), + STR_FMT(&uri)); -+ if(sca_parse_uri(&sf, &uri) < 0) ++ from->flags = SCA_UTIL_FLAG_TO_BODY_ALLOC; ++ from->hdr = pkg_malloc(sizeof(struct to_body)); ++ if(from->hdr == NULL) { ++ PKG_MEM_ERROR; + return -1; -+ *from = &sf; -+ } ++ } ++ if(sca_parse_uri(from->hdr, &uri) < 0) ++ return -1; + } +- *to = t; +- return (0); } @@ -685,13 +1055,11 @@ index 4ab4c6f..e1ef561 100644 - * caller needs to call free_to for *body - */ -int sca_build_to_body_from_uri(sip_msg_t *msg, struct to_body **body, str *uri) -+int sca_get_msg_to_header(sip_msg_t *msg, struct to_body **to) ++int sca_get_msg_to_header(sip_msg_t *msg, sca_to_body_t *to) { - assert(msg != NULL); - assert(body != NULL); - assert(uri != NULL); -+ static struct to_body parsed_to; -+ struct to_body *t = NULL; + str uri = STR_NULL; - *body = pkg_malloc(sizeof(struct to_body)); @@ -700,6 +1068,7 @@ index 4ab4c6f..e1ef561 100644 - return (-1); - } + assert(to != NULL); ++ memset(to, 0, sizeof(sca_to_body_t)); + if(sca_get_avp_value(to_uri_avp_type, to_uri_avp, &uri) < 0) { + assert(msg != NULL); @@ -712,33 +1081,132 @@ index 4ab4c6f..e1ef561 100644 + LM_ERR("Empty To header\n"); + return (-1); + } -+ t = get_to(msg); -+ if(t == NULL) { ++ to->flags = SCA_UTIL_FLAG_TO_BODY_MSG; ++ to->hdr = get_to(msg); ++ if(to->hdr == NULL) { + parse_to(msg->to->body.s, + msg->to->body.s + msg->to->body.len + 1, // end of buffer -+ &parsed_to); -+ if(parsed_to.error != PARSE_OK) { ++ to->hdr); ++ if(to->hdr->error != PARSE_OK) { + LM_ERR("Bad To header\n"); + return (-1); + } -+ t = &parsed_to; + } + + // ensure the URI is parsed for future use -+ if(parse_uri(t->uri.s, t->uri.len, GET_TO_PURI(msg)) < 0) { -+ LM_ERR("Failed to parse To URI %.*s\n", STR_FMT(&t->uri)); ++ if(parse_uri(to->hdr->uri.s, to->hdr->uri.len, GET_TO_PURI(msg)) < 0) { ++ LM_ERR("Failed to parse To URI %.*s\n", STR_FMT(&to->hdr->uri)); + return (-1); + } -+ -+ *to = t; + } else { + LM_DBG("using $avp(%.*s)[%.*s] as to uri\n", STR_FMT(&to_uri_avp.s), + STR_FMT(&uri)); -+ if(sca_parse_uri(&parsed_to, &uri) < 0) ++ to->hdr = pkg_malloc(sizeof(struct to_body)); ++ if(to->hdr == NULL) { ++ PKG_MEM_ERROR; ++ return -1; ++ } ++ to->flags = SCA_UTIL_FLAG_TO_BODY_ALLOC; ++ if(sca_parse_uri(to->hdr, &uri) < 0) + return -1; -+ *to = &parsed_to; } + return (0); } +@@ -354,7 +389,7 @@ int sca_aor_create_from_info( + + int sca_create_canonical_aor_for_ua(sip_msg_t *msg, str *c_aor, int ua_opts) + { +- struct to_body *tf = NULL; ++ sca_to_body_t tf; + sip_uri_t c_uri; + str tf_aor = STR_NULL; + str contact_uri = STR_NULL; +@@ -364,6 +399,7 @@ int sca_create_canonical_aor_for_ua(sip_msg_t *msg, str *c_aor, int ua_opts) + assert(c_aor != NULL); + + memset(c_aor, 0, sizeof(str)); ++ memset(&tf, 0, sizeof(sca_to_body_t)); + + if((ua_opts & SCA_AOR_TYPE_AUTO)) { + if(msg->first_line.type == SIP_REQUEST) { +@@ -385,10 +421,10 @@ int sca_create_canonical_aor_for_ua(sip_msg_t *msg, str *c_aor, int ua_opts) + } + } + +- if(sca_uri_extract_aor(&tf->uri, &tf_aor) < 0) { ++ if(sca_uri_extract_aor(&tf.hdr->uri, &tf_aor) < 0) { + LM_ERR("sca_create_canonical_aor: failed to extract AoR from " + "URI <%.*s>\n", +- STR_FMT(&tf->uri)); ++ STR_FMT(&tf.hdr->uri)); + goto done; + } + +@@ -410,7 +446,7 @@ int sca_create_canonical_aor_for_ua(sip_msg_t *msg, str *c_aor, int ua_opts) + } + + if(SCA_STR_EMPTY(&c_uri.user) +- || SCA_STR_EQ(&c_uri.user, &tf->parsed_uri.user)) { ++ || SCA_STR_EQ(&c_uri.user, &tf.hdr->parsed_uri.user)) { + // empty contact header or Contact user matches To/From AoR + c_aor->s = (char *)pkg_malloc(tf_aor.len); + c_aor->len = tf_aor.len; +@@ -418,7 +454,7 @@ int sca_create_canonical_aor_for_ua(sip_msg_t *msg, str *c_aor, int ua_opts) + } else { + // Contact user and To/From user mismatch + if(sca_aor_create_from_info(c_aor, c_uri.type, &c_uri.user, +- &tf->parsed_uri.host, &tf->parsed_uri.port) ++ &tf.hdr->parsed_uri.host, &tf.hdr->parsed_uri.port) + < 0) { + LM_ERR("sca_create_canonical_aor: failed to create AoR from " + "Contact <%.*s> and URI <%.*s>\n", +@@ -430,6 +466,9 @@ int sca_create_canonical_aor_for_ua(sip_msg_t *msg, str *c_aor, int ua_opts) + rc = 1; + + done: ++ if(tf.flags & SCA_UTIL_FLAG_TO_BODY_ALLOC) { ++ free_to(tf.hdr); ++ } + return (rc); + } + +diff --git a/src/modules/sca/sca_util.h b/src/modules/sca/sca_util.h +index c191083..563dedc 100644 +--- a/src/modules/sca/sca_util.h ++++ b/src/modules/sca/sca_util.h +@@ -29,6 +29,18 @@ enum + SCA_AOR_TYPE_UAS = (1 << 2), + }; + ++enum ++{ ++ SCA_UTIL_FLAG_TO_BODY_MSG = (1 << 0), ++ SCA_UTIL_FLAG_TO_BODY_ALLOC = (1 << 1), ++}; ++ ++typedef struct sca_to_body ++{ ++ struct to_body *hdr; ++ unsigned int flags; ++} sca_to_body_t; ++ + // get method, regardless of whether message is a request or response + int sca_get_msg_method(sip_msg_t *); + +@@ -42,12 +54,10 @@ int sca_get_msg_cseq_number(sip_msg_t *); + int sca_get_msg_cseq_method(sip_msg_t *); + + // convenient From header parsing and extraction +-int sca_get_msg_from_header(sip_msg_t *, struct to_body **); ++int sca_get_msg_from_header(sip_msg_t *, sca_to_body_t *); + + // convenient To header parsing and extraction +-int sca_get_msg_to_header(sip_msg_t *, struct to_body **); +- +-int sca_build_to_body_from_uri(sip_msg_t *, struct to_body **, str *); ++int sca_get_msg_to_header(sip_msg_t *, sca_to_body_t *); + + // count number of characters requiring escape as defined by escape_common + int sca_uri_display_escapes_count(str *); diff --git a/debian/patches/sipwise/sca-rr-is-direction.patch b/debian/patches/sipwise/sca-rr-is-direction.patch index fa7c11024..6c8c4c7dc 100644 --- a/debian/patches/sipwise/sca-rr-is-direction.patch +++ b/debian/patches/sipwise/sca-rr-is-direction.patch @@ -3,11 +3,11 @@ Date: Thu, 26 Mar 2020 10:06:46 +0100 Subject: sca-rr-is-direction --- - src/modules/sca/sca.c | 7 ++++++ + src/modules/sca/sca.c | 7 +++++ src/modules/sca/sca.h | 1 + - src/modules/sca/sca_call_info.c | 53 ++++++++++++++++++++++++++++++++--------- + src/modules/sca/sca_call_info.c | 59 +++++++++++++++++++++++++++++++++-------- src/modules/sca/sca_common.h | 1 + - 4 files changed, 51 insertions(+), 11 deletions(-) + 4 files changed, 57 insertions(+), 11 deletions(-) diff --git a/src/modules/sca/sca.c b/src/modules/sca/sca.c index c2347bb..c0042b9 100644 @@ -47,28 +47,28 @@ index 7a80847..3d08921 100644 }; typedef struct _sca_mod sca_mod; diff --git a/src/modules/sca/sca_call_info.c b/src/modules/sca/sca_call_info.c -index a173294..00a4c0e 100644 +index d83fe48..8734d3a 100644 --- a/src/modules/sca/sca_call_info.c +++ b/src/modules/sca/sca_call_info.c -@@ -1353,6 +1353,7 @@ void sca_call_info_ack_from_handler(sip_msg_t *msg, str *from_aor, str *to_aor) +@@ -1362,6 +1362,7 @@ void sca_call_info_ack_from_handler(sip_msg_t *msg, str *from_aor, str *to_aor) + { sca_appearance *app; - struct to_body *from; - struct to_body *to; + sca_to_body_t from, to; + str *tag; int slot_idx = -1; int state = SCA_APPEARANCE_STATE_IDLE; -@@ -1366,13 +1367,19 @@ void sca_call_info_ack_from_handler(sip_msg_t *msg, str *from_aor, str *to_aor) +@@ -1378,13 +1379,19 @@ void sca_call_info_ack_from_handler(sip_msg_t *msg, str *from_aor, str *to_aor) } if(sca_uri_lock_if_shared_appearance(sca, from_aor, &slot_idx)) { - app = sca_appearance_for_tags_unsafe(sca, from_aor, &msg->callid->body, -- &from->tag_value, NULL, slot_idx); +- &from.hdr->tag_value, NULL, slot_idx); + if(sca->rr_api->is_direction(msg, RR_FLOW_UPSTREAM) == 0) { + LM_DBG("upstream direction detected\n"); -+ tag = &to->tag_value; ++ tag = &to.hdr->tag_value; + } else { -+ tag = &from->tag_value; ++ tag = &from.hdr->tag_value; + } + app = sca_appearance_for_tags_unsafe( + sca, from_aor, &msg->callid->body, tag, NULL, slot_idx); @@ -76,47 +76,60 @@ index a173294..00a4c0e 100644 LM_ERR("sca_call_info_ack_cb: No appearance for %.*s matching " "call-id <%.*s> and from-tag <%.*s>\n", STR_FMT(from_aor), STR_FMT(&msg->callid->body), -- STR_FMT(&from->tag_value)); +- STR_FMT(&from.hdr->tag_value)); + STR_FMT(tag)); goto done; } -@@ -1411,11 +1418,12 @@ done: +@@ -1429,11 +1436,15 @@ done: /* XXX needs extract routines */ void sca_call_info_ack_cb(struct cell *t, int type, struct tmcb_params *params) { -- struct to_body *to; -+ struct to_body *to, *from; +- sca_to_body_t to; ++ sca_to_body_t to, from; sca_appearance *app = NULL; str from_aor = STR_NULL; str to_aor = STR_NULL; int slot_idx = -1; + str *tag; ++ ++ memset(&to, 0, sizeof(sca_to_body_t)); ++ memset(&from, 0, sizeof(sca_to_body_t)); + + memset(&to, 0, sizeof(to)); - if(!(type & TMCB_E2EACK_IN)) { - return; -@@ -1444,8 +1452,18 @@ void sca_call_info_ack_cb(struct cell *t, int type, struct tmcb_params *params) +@@ -1464,8 +1475,18 @@ void sca_call_info_ack_cb(struct cell *t, int type, struct tmcb_params *params) } // on ACK, ensure SCA callee state is promoted to ACTIVE. - app = sca_appearance_for_tags_unsafe(sca, &to_aor, -- ¶ms->req->callid->body, &to->tag_value, NULL, slot_idx); +- ¶ms->req->callid->body, &to.hdr->tag_value, NULL, slot_idx); + if(sca->rr_api->is_direction(params->req, RR_FLOW_UPSTREAM) == 0) { + LM_DBG("upstream direction detected\n"); + if(sca_get_msg_from_header(params->req, &from) < 0) { + LM_ERR("failed to get From-header"); + goto done; + } -+ tag = &from->tag_value; ++ tag = &from.hdr->tag_value; + } else { -+ tag = &to->tag_value; ++ tag = &to.hdr->tag_value; + } + app = sca_appearance_for_tags_unsafe( + sca, &to_aor, ¶ms->req->callid->body, tag, NULL, slot_idx); if(app && app->state == SCA_APPEARANCE_STATE_ACTIVE_PENDING) { LM_DBG("promoting %.*s appearance-index %d to active\n", STR_FMT(&to_aor), app->index); -@@ -1528,6 +1546,7 @@ static int sca_call_info_bye_handler(sip_msg_t *msg, sca_call_info *call_info, +@@ -1487,6 +1508,9 @@ done: + if(from_aor.s != NULL) { + pkg_free(from_aor.s); + } ++ if(from.flags & SCA_UTIL_FLAG_TO_BODY_ALLOC) { ++ free_to(from.hdr); ++ } + if(to.flags & SCA_UTIL_FLAG_TO_BODY_ALLOC) { + free_to(to.hdr); + } +@@ -1551,6 +1575,7 @@ static int sca_call_info_bye_handler(sip_msg_t *msg, sca_call_info *call_info, sca_appearance *app = NULL; int slot_idx = -1; int rc = -1; @@ -124,7 +137,7 @@ index a173294..00a4c0e 100644 if(msg->first_line.type == SIP_REQUEST) { if(SCA_CALL_INFO_IS_SHARED_CALLER(call_info)) { -@@ -1545,14 +1564,20 @@ static int sca_call_info_bye_handler(sip_msg_t *msg, sca_call_info *call_info, +@@ -1568,14 +1593,20 @@ static int sca_call_info_bye_handler(sip_msg_t *msg, sca_call_info *call_info, } if(app == NULL) { // try to find it by tags @@ -148,7 +161,7 @@ index a173294..00a4c0e 100644 goto done; } -@@ -1593,8 +1618,14 @@ static int sca_call_info_bye_handler(sip_msg_t *msg, sca_call_info *call_info, +@@ -1616,8 +1647,14 @@ static int sca_call_info_bye_handler(sip_msg_t *msg, sca_call_info *call_info, goto done; }