From 94e6bcfd2be07308c91da7ac15ea226059a05614 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 28 Feb 2011 16:36:28 -0500 Subject: [PATCH] mod_sofia: fix bugzilla 6341 - dialplan not replacing user in contact string --- src/mod/endpoints/mod_sofia/mod_sofia.c | 184 ++++++++++++------------ 1 file changed, 93 insertions(+), 91 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 5ce681880c..82f4c2ca02 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -3552,97 +3552,6 @@ SWITCH_STANDARD_API(sofia_contact_function) } } - if (user_replacement) { - int urlcount = 0; - int copyerr = 0; - char *newreply = NULL; - char *urlstart = NULL; - char *newptr = NULL; - char *bufend = NULL; - char *str = reply; - switch_size_t copysize = 0; - switch_size_t replacesize = strlen(user_replacement); - switch_size_t allocsize = 0; - - /* first pass to count how many URLs we have */ - while ((urlstart = strcasestr(str, "sip:")) || (urlstart = strcasestr(str, "sips:"))) { - urlcount++; - str = urlstart + 4; - } - - if (!urlcount) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "sofia_contact(): no sip URLs found to replace the user\n"); - copyerr++; - goto copydone; - } - - /* this allocates a bit more than needed but better safe than sorry doing more funky math */ - allocsize = strlen(reply) + (urlcount * replacesize); - newreply = switch_core_session_alloc(session, allocsize); - if (!newreply) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "sofia_contact(): no buffer space available for replacement\n"); - copyerr++; - goto copydone; - } - - /* get a working pointer to the new reply */ - newptr = newreply; - - /* pointer to the end of the allocated buffer for safety checks */ - bufend = newreply + allocsize; - *bufend = 0; - - /* go thru all the urls and replace the user part */ - str = reply; - while ((urlstart = strcasestr(str, "sip:")) || (urlstart = strcasestr(str, "sips:"))) { - - /* found an URL, copy up to the start of the url */ - copysize = ( urlstart - str ) + 4; - - /* double check boundaries before copying anything at all (this should not happen) */ - if ((newptr + copysize + replacesize) >= bufend) { - copyerr++; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "sofia_contact(): wow buffer was not big enough!\n"); - break; - } - - /* copy the original contact string except for the user */ - memcpy(newptr, str, copysize); - newptr += copysize; - - /* copy the user replacement */ - memcpy(newptr, user_replacement, replacesize); - newptr += replacesize; - - /* skip the original user part */ - str = strchr(urlstart, '@'); - if (!str) { - copyerr++; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "sofia_contact(): not host part found for contact\n"); - break; - } - /* continue searching for the next sip: URL */ - } - -copydone: - if (!copyerr) { - /* copy the remaining reply string */ - copysize = strlen(str); - if ((newptr + copysize) >= bufend) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "sofia_contact(): wow buffer was not big enough, close, but not enough!\n"); - } else { - strcpy(newptr, str); - reply = newreply; - } - } else { - reply = "error/replacement error"; - } - } - - stream->write_function(stream, "%s", reply); - reply = NULL; - - switch_safe_free(mystream.data); } switch_mutex_unlock(mod_sofia_globals.hash_mutex); @@ -3650,6 +3559,99 @@ copydone: reply = (char *) mystream.data; + if (user_replacement) { + int urlcount = 0; + int copyerr = 0; + char *newreply = NULL; + char *urlstart = NULL; + char *newptr = NULL; + char *bufend = NULL; + char *str = reply; + switch_size_t copysize = 0; + switch_size_t replacesize = strlen(user_replacement); + switch_size_t allocsize = 0; + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "sofia_contact(): trying to replace %s in %s\n", + user_replacement, str); + + /* first pass to count how many URLs we have */ + while ((urlstart = strcasestr(str, "sip:")) || (urlstart = strcasestr(str, "sips:"))) { + urlcount++; + str = urlstart + 4; + } + + if (!urlcount) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "sofia_contact(): no sip URLs found to replace the user\n"); + copyerr++; + goto copydone; + } + + /* this allocates a bit more than needed but better safe than sorry doing more funky math */ + allocsize = strlen(reply) + (urlcount * replacesize); + newreply = switch_core_session_alloc(session, allocsize); + if (!newreply) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "sofia_contact(): no buffer space available for replacement\n"); + copyerr++; + goto copydone; + } + + /* get a working pointer to the new reply */ + newptr = newreply; + + /* pointer to the end of the allocated buffer for safety checks */ + bufend = newreply + allocsize; + *bufend = 0; + + /* go thru all the urls and replace the user part */ + str = reply; + while ((urlstart = strcasestr(str, "sip:")) || (urlstart = strcasestr(str, "sips:"))) { + + /* found an URL, copy up to the start of the url */ + copysize = ( urlstart - str ) + 4; + + /* double check boundaries before copying anything at all (this should not happen) */ + if ((newptr + copysize + replacesize) >= bufend) { + copyerr++; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "sofia_contact(): wow buffer was not big enough!\n"); + break; + } + + /* copy the original contact string except for the user */ + memcpy(newptr, str, copysize); + newptr += copysize; + + /* copy the user replacement */ + memcpy(newptr, user_replacement, replacesize); + newptr += replacesize; + + /* skip the original user part */ + str = strchr(urlstart, '@'); + if (!str) { + copyerr++; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "sofia_contact(): not host part found for contact\n"); + break; + } + /* continue searching for the next sip: URL */ + } + +copydone: + if (!copyerr) { + /* copy the remaining reply string */ + copysize = strlen(str); + if ((newptr + copysize) >= bufend) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "sofia_contact(): wow buffer was not big enough, close, but not enough!\n"); + } else { + strcpy(newptr, str); + reply = newreply; + goto end; + } + } else { + /* on error, we do nothing and just default to the original stream returned (mystream.data) */ + } + } + + reply = (char *) mystream.data; + end: if (zstr(reply)) {