Index: asterisk-1.4.17~dfsg/channels/chan_sip.c =================================================================== --- asterisk-1.4.17~dfsg.orig/channels/chan_sip.c 2009-01-27 23:36:55.000000000 +0100 +++ asterisk-1.4.17~dfsg/channels/chan_sip.c 2009-01-28 00:28:12.000000000 +0100 @@ -8884,6 +8884,23 @@ return sip_pvt_ptr; } +static const char* next_uri_query_option(const char* query_str) { + const char* curr_pos = query_str; + const char* result = NULL; + while ((curr_pos = strchr(curr_pos, '&')) != NULL) { // Search for option separator + if (curr_pos > query_str && *(curr_pos - 1) == '\\') { + // Escaped option separator found, try next + continue; + }else { + // There must be one more char (could the '\0') + // Return its string position + result = ++curr_pos; + break; + } + } + return result; +} + /*! \brief Call transfer support (the REFER method) * Extracts Refer headers into pvt dialog structure */ static int get_refer_info(struct sip_pvt *transferer, struct sip_request *outgoing_req) @@ -8949,7 +8966,16 @@ /* Check for arguments in the refer_to header */ if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */ *ptr++ = '\0'; - if (!strncasecmp(ptr, "REPLACES=", 9)) { + // Search for 'replaces=' option + char* replaces_option = NULL; + do { + if (!strncasecmp(ptr, "REPLACES=", 9)) { + replaces_option = ptr; + break; + } + }while((ptr = (char*)next_uri_query_option(ptr)) != NULL); + + if(replaces_option != NULL) { char *to = NULL, *from = NULL; /* This is an attended transfer */