From 3d5a816f42e6599839e104f12b9b9463ca6817a5 Mon Sep 17 00:00:00 2001 From: Victor Seva Date: Fri, 21 Oct 2016 12:12:25 +0200 Subject: [PATCH] TT#2391 sca fixes * use server_address as contact of SUBSCRIBE reply too * use To header info as target of SUBSCRIBE when in-dialog * fix sca_call_info_update() params * change onhold_bflag parameter behavior Change-Id: I5d112e9187ed6eccce0c44422605482530ab7671 --- debian/patches/series | 3 + .../sca-add-server_address-parameter.patch | 24 +- .../sca-fix-sca_call_info_update-params.patch | 376 ++++++++++++++++++ ...use-To-header-if-in-dialog-as-target.patch | 35 ++ ...use-onhold_bflag-value-only-when-set.patch | 49 +++ 5 files changed, 480 insertions(+), 7 deletions(-) create mode 100644 debian/patches/sipwise/sca-fix-sca_call_info_update-params.patch create mode 100644 debian/patches/sipwise/sca-use-To-header-if-in-dialog-as-target.patch create mode 100644 debian/patches/sipwise/sca-use-onhold_bflag-value-only-when-set.patch diff --git a/debian/patches/series b/debian/patches/series index 4e9634eb1..bf386056b 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -31,4 +31,7 @@ sipwise/sca-add-server_address-parameter.patch sipwise/lib-srdb1-sca-add-server_id.patch sipwise/sca-use-new-server_id-column.patch sipwise/utils-kamctl-refresh-dbschema.patch +sipwise/sca-use-To-header-if-in-dialog-as-target.patch +sipwise/sca-fix-sca_call_info_update-params.patch +sipwise/sca-use-onhold_bflag-value-only-when-set.patch ## diff --git a/debian/patches/sipwise/sca-add-server_address-parameter.patch b/debian/patches/sipwise/sca-add-server_address-parameter.patch index b54903ce3..001afda82 100644 --- a/debian/patches/sipwise/sca-add-server_address-parameter.patch +++ b/debian/patches/sipwise/sca-add-server_address-parameter.patch @@ -12,8 +12,6 @@ Change-Id: I8f0a93f180cafc4f014f621a413fcb5f6e672f46 modules/sca/sca_notify.c | 14 +++++++++++--- 3 files changed, 17 insertions(+), 3 deletions(-) -diff --git a/modules/sca/sca.c b/modules/sca/sca.c -index f46fb1b..9dd0143 100644 --- a/modules/sca/sca.c +++ b/modules/sca/sca.c @@ -111,6 +111,7 @@ int call_info_max_expires = 3600; @@ -42,8 +40,6 @@ index f46fb1b..9dd0143 100644 return( 0 ); } -diff --git a/modules/sca/sca.h b/modules/sca/sca.h -index f5dd225..abcbe56 100644 --- a/modules/sca/sca.h +++ b/modules/sca/sca.h @@ -38,6 +38,7 @@ struct _sca_config { @@ -54,11 +50,9 @@ index f5dd225..abcbe56 100644 }; typedef struct _sca_config sca_config; -diff --git a/modules/sca/sca_notify.c b/modules/sca/sca_notify.c -index e8cbdba..89d8bb4 100644 --- a/modules/sca/sca_notify.c +++ b/modules/sca/sca_notify.c -@@ -189,15 +189,23 @@ sca_notify_append_contact_header( sca_subscription *sub, +@@ -189,15 +189,23 @@ sca_notify_append_contact_header( sca_su char *hdrbuf, int maxlen ) { int len = strlen( "Contact: " ); @@ -85,3 +79,19 @@ index e8cbdba..89d8bb4 100644 memcpy( hdrbuf + len, CRLF, strlen( CRLF )); len += strlen( CRLF ); +--- a/modules/sca/sca_subscribe.c ++++ b/modules/sca/sca_subscribe.c +@@ -1407,7 +1407,12 @@ sca_subscription_reply( sca_mod *scam, i + extra_headers.len = len; + + SCA_STR_APPEND_CSTR( &extra_headers, "Contact: " ); +- SCA_STR_APPEND( &extra_headers, &REQ_LINE( msg ).uri ); ++ if (sca->cfg->server_address != NULL) { ++ SCA_STR_APPEND( &extra_headers, sca->cfg->server_address); ++ } ++ else { ++ SCA_STR_APPEND( &extra_headers, &REQ_LINE( msg ).uri ); ++ } + SCA_STR_APPEND_CSTR( &extra_headers, CRLF ); + + SCA_STR_COPY_CSTR( &extra_headers, diff --git a/debian/patches/sipwise/sca-fix-sca_call_info_update-params.patch b/debian/patches/sipwise/sca-fix-sca_call_info_update-params.patch new file mode 100644 index 000000000..7f24ca8e4 --- /dev/null +++ b/debian/patches/sipwise/sca-fix-sca_call_info_update-params.patch @@ -0,0 +1,376 @@ +From: Victor Seva +Date: Fri, 21 Oct 2016 18:45:59 +0200 +Subject: sca: fix sca_call_info_update() params + +Change-Id: I6c47ab8ac6bffd328d36f6f134f56b4d0b141dc0 +--- + modules/sca/sca.c | 22 ++++++++- + modules/sca/sca_call_info.c | 116 +++++++++++++++++++++++++++++--------------- + modules/sca/sca_call_info.h | 2 +- + modules/sca/sca_util.c | 78 +++++++++-------------------- + modules/sca/sca_util.h | 5 +- + 5 files changed, 122 insertions(+), 101 deletions(-) + +diff --git a/modules/sca/sca.c b/modules/sca/sca.c +index 9dd0143..9e03f6f 100644 +--- a/modules/sca/sca.c ++++ b/modules/sca/sca.c +@@ -409,12 +409,30 @@ static int sca_call_info_update_1_f(sip_msg_t* msg, char* p1) { + return sca_call_info_update(msg, p1, NULL, NULL); + } + static int sca_call_info_update_2_f(sip_msg_t* msg, char* p1, char* p2) { +- return sca_call_info_update(msg, p1, p2, NULL); ++ str uri_to = STR_NULL; ++ if(get_str_fparam(&uri_to, msg, (gparam_p)p2)!=0) ++ { ++ LM_ERR("unable to get value from param pvar_to\n"); ++ return -1; ++ } ++ return sca_call_info_update(msg, p1, &uri_to, NULL); + } + static int sca_call_info_update_3_f(sip_msg_t* msg, + char* p1, char* p2, char * p3) + { +- return sca_call_info_update(msg, p1, p2, p3); ++ str uri_to = STR_NULL; ++ str uri_from = STR_NULL; ++ if(get_str_fparam(&uri_to, msg, (gparam_p)p2)!=0) ++ { ++ LM_ERR("unable to get value from param pvar_to\n"); ++ return -1; ++ } ++ if(get_str_fparam(&uri_from, msg, (gparam_p)p3)!=0) ++ { ++ LM_ERR("unable to get value from param pvar_from\n"); ++ return -1; ++ } ++ return sca_call_info_update(msg, p1, &uri_to, &uri_from); + } + + int fixup_ciu(void **param, int param_no) +diff --git a/modules/sca/sca_call_info.c b/modules/sca/sca_call_info.c +index a5854cc..d46c65d 100644 +--- a/modules/sca/sca_call_info.c ++++ b/modules/sca/sca_call_info.c +@@ -1863,7 +1863,7 @@ struct sca_call_info_dispatch call_info_dispatch[] = { + #define SCA_CALL_INFO_UPDATE_FLAG_FROM_ALLOC (1 << 0) + #define SCA_CALL_INFO_UPDATE_FLAG_TO_ALLOC (1 << 1) + int +-sca_call_info_update( sip_msg_t *msg, char *p1, char *p2, char *p3 ) ++sca_call_info_update( sip_msg_t *msg, char *p1, str *uri_to, str *uri_from ) + { + sca_call_info call_info; + hdr_field_t *call_info_hdr; +@@ -1874,6 +1874,7 @@ sca_call_info_update( sip_msg_t *msg, char *p1, char *p2, char *p3 ) + str to_aor = STR_NULL; + str contact_uri = STR_NULL; + int aor_flags = SCA_CALL_INFO_UPDATE_FLAG_DEFAULT; ++ int to_body_flags = SCA_CALL_INFO_UPDATE_FLAG_DEFAULT; + int n_dispatch; + int i; + int method; +@@ -1888,17 +1889,19 @@ sca_call_info_update( sip_msg_t *msg, char *p1, char *p2, char *p3 ) + break; + } + } +- if ( i >= n_dispatch ) { +- LM_DBG( "BUG: sca module does not support Call-Info headers " +- "in %.*s requests", STR_FMT( &get_cseq( msg )->method )); +- return( 1 ); +- } + + if ( parse_headers( msg, HDR_EOH_F, 0 ) < 0 ) { + LM_ERR( "header parsing failed: bad request" ); + return( -1 ); + } + ++ if ( i >= n_dispatch ) { ++ LM_DBG( "BUG: sca module does not support Call-Info headers " ++ "in %.*s requests", STR_FMT( &get_cseq( msg )->method )); ++ return( 1 ); ++ } ++ ++ + if ( p1 != NULL ) { + if ( get_int_fparam( &update_mask, msg, (fparam_t *)p1 ) < 0 ) { + if(msg->cseq==NULL && ((parse_headers(msg, HDR_CSEQ_F, 0)==-1) || +@@ -1939,25 +1942,39 @@ sca_call_info_update( sip_msg_t *msg, char *p1, char *p2, char *p3 ) + } + } + +- if (p3 != NULL) { +- if (sca_get_pv_from_header(msg, &from, (pv_spec_t *) p3) < 0) { +- LM_ERR("Bad From pvar\n"); +- return (-1); ++ if (uri_from != NULL) { ++ if(sca_build_to_body_from_uri(msg, &from, uri_from)<0){ ++ LM_ERR( "Bad From uri from param\n" ); ++ return( -1 ); ++ } ++ LM_DBG("from[%.*s] param\n", STR_FMT(uri_from)); ++ to_body_flags |= SCA_CALL_INFO_UPDATE_FLAG_FROM_ALLOC; ++ if ( sca_uri_extract_aor( &from->uri, &from_aor ) < 0 ) { ++ LM_ERR( "Failed to extract AoR from From URI %.*s", ++ STR_FMT( &from->uri )); ++ goto done; + } + } + else if ( sca_get_msg_from_header( msg, &from ) < 0 ) { + LM_ERR( "Bad From header" ); + return( -1 ); + } +- if (p2 != NULL) { +- if (sca_get_pv_to_header(msg, &to, (pv_spec_t *) p2) < 0) { +- LM_ERR("Bad To pvar\n"); +- return (-1); +- } ++ if (uri_to != NULL) { ++ if(sca_build_to_body_from_uri(msg, &to, uri_to)<0){ ++ LM_ERR( "Bad From uri to param\n" ); ++ goto done; ++ } ++ LM_DBG("to[%.*s] param\n", STR_FMT(uri_to)); ++ to_body_flags |= SCA_CALL_INFO_UPDATE_FLAG_TO_ALLOC; ++ if ( sca_uri_extract_aor( &to->uri, &to_aor ) < 0 ) { ++ LM_ERR( "Failed to extract AoR from To URI %.*s", ++ STR_FMT( &to->uri )); ++ goto done; ++ } + } + else if ( sca_get_msg_to_header( msg, &to ) < 0 ) { + LM_ERR( "Bad To header" ); +- return( -1 ); ++ goto done; + } + + memset( &c_uri, 0, sizeof( sip_uri_t )); +@@ -1967,39 +1984,50 @@ sca_call_info_update( sip_msg_t *msg, char *p1, char *p2, char *p3 ) + if ( parse_uri( contact_uri.s, contact_uri.len, &c_uri ) < 0 ) { + LM_ERR( "Failed to parse Contact URI %.*s", + STR_FMT( &contact_uri )); +- return( -1 ); ++ rc = -1; ++ goto done; + } + } else if ( rc < 0 ) { + LM_ERR( "Bad Contact" ); +- return( -1 ); ++ goto done; + } + /* reset rc to -1 so we don't end up returning 0 to the script */ + rc = -1; + + /* reconcile mismatched Contact users and To/From URIs */ + if ( msg->first_line.type == SIP_REQUEST ) { +- if ( sca_create_canonical_aor( msg, &from_aor ) < 0 ) { +- return( -1 ); +- } +- aor_flags |= SCA_CALL_INFO_UPDATE_FLAG_FROM_ALLOC; +- +- if ( sca_uri_extract_aor( &to->uri, &to_aor ) < 0 ) { +- LM_ERR( "Failed to extract AoR from To URI %.*s", +- STR_FMT( &to->uri )); +- goto done; +- } ++ if(uri_from==NULL) { ++ if ( sca_create_canonical_aor( msg, &from_aor ) < 0 ) { ++ goto done; ++ } ++ aor_flags |= SCA_CALL_INFO_UPDATE_FLAG_FROM_ALLOC; ++ } ++ if(uri_to==NULL) { ++ if ( sca_uri_extract_aor( &to->uri, &to_aor ) < 0 ) { ++ LM_ERR( "Failed to extract AoR from To URI %.*s", ++ STR_FMT( &to->uri )); ++ goto done; ++ } ++ } + } else { +- if ( sca_uri_extract_aor( &from->uri, &from_aor ) < 0 ) { +- LM_ERR( "Failed to extract AoR from From URI %.*s", +- STR_FMT( &from->uri )); +- goto done; +- } +- if ( sca_create_canonical_aor( msg, &to_aor ) < 0 ) { +- return( -1 ); +- } +- aor_flags |= SCA_CALL_INFO_UPDATE_FLAG_TO_ALLOC; ++ if(uri_from==NULL) { ++ if ( sca_uri_extract_aor( &from->uri, &from_aor ) < 0 ) { ++ LM_ERR( "Failed to extract AoR from From URI %.*s", ++ STR_FMT( &from->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; ++ } + } + ++ LM_DBG("to_aor[%.*s] from_aor[%.*s]\n", ++ STR_FMT(&to_aor), STR_FMT(&from_aor)); ++ + /* early check to see if we're dealing with any SCA endpoints */ + if ( sca_uri_is_shared_appearance( sca, &from_aor )) { + if (( update_mask & SCA_CALL_INFO_SHARED_CALLER )) { +@@ -2032,7 +2060,8 @@ sca_call_info_update( sip_msg_t *msg, char *p1, char *p2, char *p3 ) + + if ( sca_call_info_header_remove( msg ) < 0 ) { + LM_ERR( "Failed to remove Call-Info header" ); +- return( -1 ); ++ rc = -1; ++ goto done; + } + + if ( call_info.ua_shared == SCA_CALL_INFO_SHARED_NONE ) { +@@ -2059,6 +2088,15 @@ done: + pkg_free( to_aor.s ); + } + } +- ++ if (( to_body_flags & SCA_CALL_INFO_UPDATE_FLAG_FROM_ALLOC )) { ++ if ( from != NULL ) { ++ free_to( from ); ++ } ++ } ++ if (( to_body_flags & SCA_CALL_INFO_UPDATE_FLAG_TO_ALLOC )) { ++ if ( to != NULL ) { ++ free_to( to ); ++ } ++ } + return( rc ); + } +diff --git a/modules/sca/sca_call_info.h b/modules/sca/sca_call_info.h +index 2806cb7..1171701 100644 +--- a/modules/sca/sca_call_info.h ++++ b/modules/sca/sca_call_info.h +@@ -63,7 +63,7 @@ typedef struct _sca_call_info sca_call_info; + extern const str SCA_CALL_INFO_HEADER_STR; + + +-int sca_call_info_update( sip_msg_t *, char *, char * , char *); ++int sca_call_info_update( sip_msg_t *, char *, str*, str* ); + void sca_call_info_sl_reply_cb( void * ); + void sca_call_info_ack_cb( struct cell *, int, struct tmcb_params * ); + +diff --git a/modules/sca/sca_util.c b/modules/sca/sca_util.c +index 721810d..60c178c 100644 +--- a/modules/sca/sca_util.c ++++ b/modules/sca/sca_util.c +@@ -114,6 +114,28 @@ sca_get_msg_cseq_method( sip_msg_t *msg ) + return( get_cseq( msg )->method_id ); + } + ++/* 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) ++{ ++ assert( msg != NULL ); ++ assert( body != NULL ); ++ assert( uri != NULL ); ++ ++ *body = pkg_malloc(sizeof(struct to_body)); ++ if(*body == NULL) { ++ LM_ERR("cannot allocate pkg memory\n"); ++ return(-1); ++ } ++ ++ parse_to(uri->s, uri->s + uri->len + 1, *body); ++ if ((*body)->error != PARSE_OK) { ++ LM_ERR("Bad uri value[%.*s]\n", STR_FMT(uri)); ++ free_to(*body); ++ return(-1); ++ } ++ return (0); ++} + + int + sca_get_msg_from_header( sip_msg_t *msg, struct to_body **from ) +@@ -184,62 +206,6 @@ sca_get_msg_to_header( sip_msg_t *msg, struct to_body **to ) + return( 0 ); + } + +-int sca_get_pv_from_header(sip_msg_t *msg, struct to_body **from, pv_spec_t *sp) +-{ +- struct to_body parsed_from; +- pv_value_t pv_val; +- +- assert(msg != NULL); +- assert(from != NULL); +- assert(sp != NULL); +- +- if (pv_get_spec_value(msg, sp, &pv_val) < 0) { +- LM_ERR("can't get value from to_pvar\n"); +- return (-1); +- } +- if (pv_val.flags & PV_VAL_STR) { +- parse_to(pv_val.rs.s, pv_val.rs.s + pv_val.rs.len + 1, &parsed_from); +- if (parsed_from.error != PARSE_OK) { +- LM_ERR("Bad From value from from_pvar\n"); +- return (-1); +- } +- *from = &parsed_from; +- return (0); +- } +- else { +- LM_ERR("value from from_pvar is not a string\n"); +- } +- return (-1); +-} +- +-int sca_get_pv_to_header(sip_msg_t *msg, struct to_body **to, pv_spec_t *sp) +-{ +- struct to_body parsed_to; +- pv_value_t pv_val; +- +- assert(msg != NULL); +- assert(to != NULL); +- assert(sp != NULL); +- +- if (pv_get_spec_value(msg, sp, &pv_val) < 0) { +- LM_ERR("can't get value from to_pvar\n"); +- return (-1); +- } +- if (pv_val.flags & PV_VAL_STR) { +- parse_to(pv_val.rs.s, pv_val.rs.s + pv_val.rs.len + 1, &parsed_to); +- if (parsed_to.error != PARSE_OK) { +- LM_ERR("Bad To value from to_pvar\n"); +- return (-1); +- } +- *to = &parsed_to; +- return (0); +- } +- else { +- LM_ERR("value from to_pvar is not a string\n"); +- } +- return (-1); +-} +- + /* count characters requiring escape as defined by escape_common */ + int + sca_uri_display_escapes_count( str *display ) +diff --git a/modules/sca/sca_util.h b/modules/sca/sca_util.h +index 4a08dba..fdaf149 100644 +--- a/modules/sca/sca_util.h ++++ b/modules/sca/sca_util.h +@@ -40,15 +40,14 @@ int sca_get_msg_cseq_number( sip_msg_t * ); + /* convenient extraction of cseq method from Cseq header */ + int sca_get_msg_cseq_method( sip_msg_t * ); + ++int sca_build_to_body_from_uri(sip_msg_t *, struct to_body **, str *); ++ + /* convenient From header parsing and extraction */ + int sca_get_msg_from_header( sip_msg_t *, struct to_body ** ); + + /* convenient To header parsing and extraction */ + int sca_get_msg_to_header( sip_msg_t *, struct to_body ** ); + +-int sca_get_pv_from_header(sip_msg_t *, struct to_body **, pv_spec_t *); +-int sca_get_pv_to_header(sip_msg_t *, struct to_body **, pv_spec_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-use-To-header-if-in-dialog-as-target.patch b/debian/patches/sipwise/sca-use-To-header-if-in-dialog-as-target.patch new file mode 100644 index 000000000..f70b19ebc --- /dev/null +++ b/debian/patches/sipwise/sca-use-To-header-if-in-dialog-as-target.patch @@ -0,0 +1,35 @@ +From: Victor Seva +Date: Fri, 21 Oct 2016 13:44:47 +0200 +Subject: sca: use To header if in-dialog as target + +Change-Id: I4ce7628da2b481d06895eeea33f564c33163f285 +--- + modules/sca/sca_subscribe.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/modules/sca/sca_subscribe.c b/modules/sca/sca_subscribe.c +index 0d797da..25fac54 100644 +--- a/modules/sca/sca_subscribe.c ++++ b/modules/sca/sca_subscribe.c +@@ -1124,14 +1124,17 @@ sca_subscription_from_request( sca_mod *scam, sip_msg_t *msg, int event_type, + goto error; + } + } +- } +- +- req_sub->subscriber = contact_uri; +- if ( sca_uri_extract_aor( ruri, &req_sub->target_aor) < 0) { ++ if ( sca_uri_extract_aor( ruri, &req_sub->target_aor) < 0) { + LM_ERR( "Failed to extract AoR from RURI %.*s", + STR_FMT( ruri )); + goto error; + } ++ } ++ else { ++ req_sub->target_aor = to->uri; ++ } ++ ++ req_sub->subscriber = contact_uri; + req_sub->event = event_type; + req_sub->index = SCA_CALL_INFO_APPEARANCE_INDEX_ANY; + req_sub->expires = expires; diff --git a/debian/patches/sipwise/sca-use-onhold_bflag-value-only-when-set.patch b/debian/patches/sipwise/sca-use-onhold_bflag-value-only-when-set.patch new file mode 100644 index 000000000..97211b6ef --- /dev/null +++ b/debian/patches/sipwise/sca-use-onhold_bflag-value-only-when-set.patch @@ -0,0 +1,49 @@ +From: Victor Seva +Date: Mon, 24 Oct 2016 11:34:39 +0200 +Subject: sca: use onhold_bflag value only when set + +Change-Id: Icc6d7edd407299b6de2f85ad8ecc5fe8d9b89339 +--- + modules/sca/doc/sca_admin.xml | 3 ++- + modules/sca/sca_util.c | 7 +++++-- + 2 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/modules/sca/doc/sca_admin.xml b/modules/sca/doc/sca_admin.xml +index 1108126..b376e41 100644 +--- a/modules/sca/doc/sca_admin.xml ++++ b/modules/sca/doc/sca_admin.xml +@@ -268,7 +268,8 @@ modparam( "sca", "db_update_interval", 120 ) + + + Which branch flag should be used by the module to identify if the call +- is on-hold instead of parsing the sdp. ++ is on-hold instead of parsing the sdp. If the bflag not is set the ++ sdp will be parsed. + + + +diff --git a/modules/sca/sca_util.c b/modules/sca/sca_util.c +index 60c178c..32a20bc 100644 +--- a/modules/sca/sca_util.c ++++ b/modules/sca/sca_util.c +@@ -454,8 +454,10 @@ sca_call_is_held( sip_msg_t *msg ) + int rc; + + if(sca->cfg->onhold_bflag >= 0) { +- LM_DBG("sca_call_is_held: skip parse_sdp and use onhold_bflag\n"); +- return isbflagset(0, (flag_t)sca->cfg->onhold_bflag); ++ if(isbflagset(0, (flag_t)sca->cfg->onhold_bflag) == 1) { ++ LM_DBG("onhold_bflag set, skip parse_sdp and set held\n"); ++ return ( 1 ); ++ } + } + rc = parse_sdp( msg ); + if ( rc < 0 ) { +@@ -475,6 +477,7 @@ sca_call_is_held( sip_msg_t *msg ) + stream != NULL; + n_str++, stream = get_sdp_stream( msg, n_sess, n_str )) { + if ( stream->is_on_hold ) { ++ LM_DBG("sca_call_is_held: parse_sdp detected stream is on hold\n"); + is_held = 1; + goto done; + }