[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.

This commit is contained in:
Aron Podrigal 2022-03-25 11:44:25 -05:00 committed by GitHub
parent df81021a11
commit 0365becc0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 35 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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) {