From 0365becc0dc43d2c5c002ae8d2653692e6e01f21 Mon Sep 17 00:00:00 2001 From: Aron Podrigal Date: Fri, 25 Mar 2022 11:44:25 -0500 Subject: [PATCH] [mod_sofia] Fix fs_path to keep `<>` so that sofia doesn't put the uri parameters as header parameters. Handle multiple `Record-Route` / `Route` and `Path` headers. --- src/mod/endpoints/mod_sofia/mod_sofia.h | 3 ++ src/mod/endpoints/mod_sofia/sofia_glue.c | 61 +++++++++++++++++++----- src/mod/endpoints/mod_sofia/sofia_reg.c | 25 ++-------- 3 files changed, 54 insertions(+), 35 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 3408b7ca0b..9c4da13a67 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -57,6 +57,8 @@ #define HAVE_FUNC 1 #endif +#define ROUTE_MAX_HEADERS 20 +#define ROUTE_ENCODED_HEADER_MAX_CHARS (1024 * 3) #define MAX_CODEC_CHECK_FRAMES 50 #define MAX_MISMATCH_FRAMES 5 #define MODNAME "mod_sofia" @@ -1260,6 +1262,7 @@ void sofia_glue_global_watchdog(switch_bool_t on); uint32_t sofia_presence_get_cseq(sofia_profile_t *profile); void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl); +char *sofia_glue_get_encoded_fs_path(nua_handle_t *nh, sip_route_t *rt, switch_bool_t add_fs_path_prefix); char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, nua_handle_t *nh, sofia_dispatch_event_t *de, sofia_nat_parse_t *np); void sofia_glue_pause_jitterbuffer(switch_core_session_t *session, switch_bool_t on); void sofia_process_dispatch_event(sofia_dispatch_event_t **dep); diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 4d37fc97f9..955b75f899 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -3294,6 +3294,44 @@ void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const } +char *sofia_glue_get_encoded_fs_path(nua_handle_t *nh, sip_route_t *rt, switch_bool_t add_fs_path_prefix) +{ + char *route = NULL; + int count = 0; + char route_buf[ROUTE_ENCODED_HEADER_MAX_CHARS] = {0}; + sip_route_t *rrp; + switch_stream_handle_t rr_stream = { 0 }; + SWITCH_STANDARD_STREAM(rr_stream); + + if (add_fs_path_prefix) { + rr_stream.write_function(&rr_stream, ";fs_path="); + } + + for(rrp = rt; rrp; rrp = rrp->r_next) { + char *sep = count == 0 ? "" : "%2C"; + char *rr = sip_header_as_string(nua_handle_home(nh), (void *) rrp); + switch_url_encode(rr, route_buf, ROUTE_ENCODED_HEADER_MAX_CHARS); + rr_stream.write_function(&rr_stream, "%s%s", sep, route_buf); + su_free(nua_handle_home(nh), rr); + + if (count >= ROUTE_MAX_HEADERS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "ROUTE_MAX_HEADERS of %d reached\n", ROUTE_MAX_HEADERS); + break; + } + count++; + } + + if (!zstr((char *) rr_stream.data)) { + route = rr_stream.data; + } else { + switch_safe_free(rr_stream.data); + } + + // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "fs_path with %d Route headers [%s]\n", count, route ? route : ""); + return route; +} + + char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, nua_handle_t *nh, sofia_dispatch_event_t *de, sofia_nat_parse_t *np) { char *contact_str = NULL; @@ -3388,19 +3426,16 @@ char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, nua } if (sip->sip_record_route) { - char *full_contact = sip_header_as_string(nua_handle_get_home(nh), (void *) contact); - char *route = sofia_glue_strip_uri(sip_header_as_string(nua_handle_get_home(nh), (void *) sip->sip_record_route)); - char *full_contact_dup; - char *route_encoded; - int route_encoded_len; - full_contact_dup = sofia_glue_get_url_from_contact(full_contact, 1); - route_encoded_len = (int)(strlen(route) * 3) + 1; - switch_zmalloc(route_encoded, route_encoded_len); - switch_url_encode(route, route_encoded, route_encoded_len); - contact_str = switch_mprintf("%s <%s;fs_path=%s>", display, full_contact_dup, route_encoded); - free(route); - free(full_contact_dup); - free(route_encoded); + char *fs_path_str = sofia_glue_get_encoded_fs_path(nh, sip->sip_record_route, SWITCH_FALSE); + char *full_contact = sip_header_as_string(nua_handle_home(nh), (void *) contact); + char *full_contact_dup = sofia_glue_get_url_from_contact(full_contact, 1); + if (fs_path_str && full_contact_dup) { + contact_str = switch_mprintf("%s <%s;fs_path=%s>", display, full_contact_dup, fs_path_str); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not get fs_path str.\n"); + } + switch_safe_free(fs_path_str); + switch_safe_free(full_contact_dup); } else if (np->is_nat && np->fs_path) { char *full_contact = sip_header_as_string(nua_handle_get_home(nh), (void *) contact); diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index d553f36d1e..a07d47b758 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -1524,30 +1524,11 @@ uint8_t sofia_reg_handle_register_token(nua_t *nua, sofia_profile_t *profile, nu if (sip->sip_path) { - char *path_stripped = NULL; - char *path_val_to_encode = NULL; - su_strlst_t *path_list = su_strlst_create(nua_handle_home(nh)); - sip_path_t *next_path = sip->sip_path; - for (; next_path; next_path = next_path->r_next) { - path_val = sip_header_as_string(nua_handle_home(nh), (void *) next_path); - if (path_val) { - path_stripped = sofia_glue_get_url_from_contact(path_val, SWITCH_TRUE); - su_free(nua_handle_home(nh), path_val); - su_strlst_dup_append(path_list, path_stripped); - switch_safe_free(path_stripped); - } + path_encoded = sofia_glue_get_encoded_fs_path(nh, sip->sip_path, SWITCH_TRUE); + if (!path_encoded) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not get fs_path str.\n"); } - path_val = su_strlst_join(path_list, nua_handle_home(nh), ","); - path_val_to_encode = su_strlst_join(path_list, nua_handle_home(nh), "%2C"); - su_strlst_destroy(path_list); - if (path_val_to_encode) { - path_encoded_len = (int)(strlen(path_val_to_encode) * 3) + 1; - switch_zmalloc(path_encoded, path_encoded_len); - switch_copy_string(path_encoded, ";fs_path=", 10); - switch_url_encode(path_val_to_encode, path_encoded + 9, path_encoded_len - 9); - su_free(nua_handle_home(nh), path_val_to_encode); - } } else if (is_nat) { char my_contact_str[1024]; if (uparams) {