]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-11557: [mod_sofia] add support for RFC 7989 Session-ID header
authorMike Jerris <mike@signalwire.com>
Wed, 5 Dec 2018 22:58:25 +0000 (02:58 +0400)
committerAndrey Volk <andywolk@gmail.com>
Wed, 17 Jul 2019 15:13:41 +0000 (19:13 +0400)
(enable with sofia profile param rfc-7989=true)

FS-11557 [mod_sofia, mod_conference, core] Add support for re-INVITE when setting Session-ID in conference after call has been answered.

FS-11557 [mod_conference] Missed a spot where APP_SESSION_ID needed to be set.

FS-11557: set session id for outbound (initial requests)

FS-11557: [mod_sofia] rename vars and functions "session id" -> "session uuid" to reflect the real meaning for rfc7989.

FS-11557: fix bug - colliding chan var names (session_id)

FS-11557: check nil session uuid

FS-11557 : replace CS_NEW with CS_INIT for when originating calls, generate new uuid.

FS-11557: handle inbound (UAS mode, one leg)

FS-11557: generic param handling and filter via new sip profile option "rfc-7989-filter", eg:
<param name="rfc-7989-filter" value="logme, sec-agree, privacy" />

FS-11557: renamed chan vars (reflect meaning only for RFC7989)

FS-11557: fallback to RFC7329 - "old" Session-ID

FS-11557: distinguish between request and replies when we read the header
(to provide compatibility with old RFC7329 - section 11 of RFC7989)
FS-11557: change more vars/consts names

FS-11557: move compat flag on the channel.

FS-11557: add Session-ID header in REFER

FS-11557: needs extra condition on received initial request

FS-11557: handle NOTIFY

FS-11557: support answer() in dialplan - it was sending back a 200 OK with Session-ID invalid, eg: A=NIL;B=X

FS-11557: add Session-ID for NOTIFY (more cases)

FS-11557: handle reply to SIP INFO (add Session-ID header)

FS-11557: handle case of BYE after REFER, when the channel is destroyed already (save the uuid on sofia_private)

FS-11557: handle more SIP reply cases (eg: 202 Accepted , more negative replies)

FS-11557: handle ACK (UAS role)

FS-11557: added "rfc-7989-force-old" profile param - to enforce old rfc7329 for the UAC role. default off.
enabled with "<param name="rfc-7989-force-old" value="true" />".

FS-11557: fallback to rfc7329 fixes.

FS-11557: set flag CF_RFC7329_COMPAT on partner channel where needed

FS-11557: fix crash (mod_conference)

src/include/switch_types.h
src/mod/applications/mod_conference/mod_conference.c
src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c

index 1f6f673b9db02b94bdafe68f1c4c11a977c9644b..43bbf12d03c3e8d93d51175cd47ca736dec56c75 100644 (file)
@@ -225,6 +225,10 @@ SWITCH_BEGIN_EXTERN_C
 #define SWITCH_EXEC_AFTER_BRIDGE_APP_VARIABLE "exec_after_bridge_app"
 #define SWITCH_EXEC_AFTER_BRIDGE_ARG_VARIABLE "exec_after_bridge_arg"
 #define SWITCH_MAX_FORWARDS_VARIABLE "max_forwards"
+#define SWITCH_RFC7989_SESSION_ID_VARIABLE "session_uuid"
+#define SWITCH_RFC7989_REMOTE_SESSION_ID_VARIABLE "remote_session_uuid"
+#define SWITCH_RFC7989_APP_SESSION_ID_VARIABLE "app_session_uuid"
+#define SWITCH_RFC7989_GENERIC_PARAM_VARIABLE "generic_param_session_uuid"
 #define SWITCH_MAX_SESSION_TRANSFERS_VARIABLE "max_session_transfers"
 #define SWITCH_DISABLE_APP_LOG_VARIABLE "disable_app_log"
 #define SWITCH_SPEECH_KEY "speech"
@@ -1159,6 +1163,7 @@ typedef enum {
        SWITCH_MESSAGE_RING_EVENT,
        SWITCH_MESSAGE_RESAMPLE_EVENT,
        SWITCH_MESSAGE_HEARTBEAT_EVENT,
+       SWITCH_MESSAGE_INDICATE_SESSION_ID,
        SWITCH_MESSAGE_INVALID
 } switch_core_session_message_types_t;
 
@@ -1607,6 +1612,7 @@ typedef enum {
        CF_ARRANGED_BRIDGE,
        CF_STATE_REPEAT,
        CF_WANT_DTLSv1_2,
+       CF_RFC7329_COMPAT,
        /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
        /* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */
        CF_FLAG_MAX
index 4337f8369817cd34deac8a698b4beed6bb49c362..36c71f7dd6251af9a088f50e2aa9083ffed4766b 100644 (file)
@@ -1911,8 +1911,8 @@ SWITCH_STANDARD_APP(conference_function)
 
        switch_channel_set_flag(channel, CF_CONFERENCE);
 
-       if (switch_channel_answer(channel) != SWITCH_STATUS_SUCCESS) {
-               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Channel answer failed.\n");
+       if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Channel pre answer failed.\n");
                goto end;
        }
 
@@ -2060,6 +2060,7 @@ SWITCH_STANDARD_APP(conference_function)
                locked = 0;
 
                switch_channel_set_variable(channel, "conference_name", conference->name);
+               switch_channel_set_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE, conference->uuid_str);
 
                /* Set the minimum number of members (once you go above it you cannot go below it) */
                conference->min = 2;
@@ -2144,6 +2145,7 @@ SWITCH_STANDARD_APP(conference_function)
                        }
 
                        switch_channel_set_variable(channel, "conference_name", conference->name);
+                       switch_channel_set_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE, conference->uuid_str);
 
                        /* Set MOH from variable if not set */
                        if (zstr(conference->moh_sound)) {
@@ -2210,6 +2212,7 @@ SWITCH_STANDARD_APP(conference_function)
                        switch_channel_api_on(channel, "api_on_conference_create");
                } else {                                /* setup user variable */
                        switch_channel_set_variable(channel, "conference_name", conference->name);
+                       switch_channel_set_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE, conference->uuid_str);
                        rl++;
                }
 
@@ -2223,6 +2226,12 @@ SWITCH_STANDARD_APP(conference_function)
                        mdpin = conference->mpin;
                }
 
+               /* Tell the channel we have a new Session-ID */
+               msg.from = __FILE__;
+               msg.message_id = SWITCH_MESSAGE_INDICATE_SESSION_ID;
+               switch_core_session_receive_message(session, &msg);
+
+               switch_channel_answer(channel);
 
                /* if this is not an outbound call, deal with conference pins */
                if (enforce_security && (!zstr(dpin) || !zstr(mdpin))) {
@@ -2233,9 +2242,6 @@ SWITCH_STANDARD_APP(conference_function)
                        switch_status_t status = SWITCH_STATUS_SUCCESS;
                        char *supplied_pin_value;
 
-                       /* Answer the channel */
-                       switch_channel_answer(channel);
-
                        /* look for PIN in channel variable first.  If not present or invalid revert to prompting user */
                        supplied_pin_value = switch_core_strdup(conference->pool, switch_channel_get_variable(channel, "supplied_pin"));
                        if (!zstr(supplied_pin_value)) {
index c203e5c114a15e590248cdde0dfcf9658f2a03fe..6b9a9d7d8418b38dd4024f90492d420b11d6c32f 100644 (file)
@@ -484,6 +484,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
                const char *val = NULL;
                const char *max_forwards = switch_channel_get_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE);
                const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full");
+               const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
 
                val = switch_channel_get_variable(tech_pvt->channel, "disable_q850_reason");
 
@@ -518,7 +519,9 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
                                                TAG_IF(!zstr(reason), SIPTAG_REASON_STR(reason)),
                                                TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
                                                TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
-                                               TAG_IF(!zstr(bye_headers), SIPTAG_HEADER_STR(bye_headers)), TAG_END());
+                                               TAG_IF(!zstr(bye_headers), SIPTAG_HEADER_STR(bye_headers)),
+                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                               TAG_END());
                        }
                } else {
                        if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
@@ -532,7 +535,9 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
                                        nua_cancel(tech_pvt->nh,
                                                           SIPTAG_CONTACT(SIP_NONE),
                                                           TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
-                                                          TAG_IF(!zstr(reason), SIPTAG_REASON_STR(reason)), TAG_IF(!zstr(bye_headers), SIPTAG_HEADER_STR(bye_headers)), TAG_END());
+                                                          TAG_IF(!zstr(reason), SIPTAG_REASON_STR(reason)), TAG_IF(!zstr(bye_headers), SIPTAG_HEADER_STR(bye_headers)),
+                                                          TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                          TAG_END());
                                }
                        } else {
                                char *resp_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_RESPONSE_HEADER_PREFIX);
@@ -618,6 +623,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
                                                                TAG_IF(!zstr(added_headers), SIPTAG_HEADER_STR(added_headers)),
                                                                TAG_IF(tech_pvt->respond_dest, SIPTAG_CONTACT_STR(tech_pvt->respond_dest)),
                                                                TAG_IF(!zstr(max_forwards), SIPTAG_MAX_FORWARDS_STR(max_forwards)),
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                                                TAG_END());
 
                                        switch_safe_free(resp_headers);
@@ -667,9 +673,10 @@ static switch_status_t sofia_on_soft_execute(switch_core_session_t *session)
 static switch_status_t sofia_acknowledge_call(switch_core_session_t *session)
 {
        struct private_object *tech_pvt = switch_core_session_get_private(session);
+       const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
 
        if (!tech_pvt->sent_100) {
-               nua_respond(tech_pvt->nh, SIP_100_TRYING, TAG_END());
+               nua_respond(tech_pvt->nh, SIP_100_TRYING, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                tech_pvt->sent_100 = 1;
                return SWITCH_STATUS_SUCCESS;
        }
@@ -690,6 +697,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
        int is_3pcc = 0;
        char *sticky = NULL;
        const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full");
+       const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
 
        if(sofia_acknowledge_call(session) == SWITCH_STATUS_SUCCESS) {
                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Dialplan did not acknowledge_call; sent 100 Trying");
@@ -726,6 +734,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
                                        SOATAG_RTP_SELECT(1),
                                        SOATAG_AUDIO_AUX("cn telephone-event"),
                                        TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
+                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                        TAG_END());
                } else {
                        nua_ack(tech_pvt->nh,
@@ -734,6 +743,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
                                        SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
                                        TAG_IF(tech_pvt->mparams.local_sdp_str, SIPTAG_CONTENT_TYPE_STR("application/sdp")),
                                        TAG_IF(tech_pvt->mparams.local_sdp_str, SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str)),
+                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                        SOATAG_AUDIO_AUX("cn telephone-event"),
                                        TAG_END());
                }
@@ -811,6 +821,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
                                                                SOATAG_RTP_SELECT(1),
                                                                SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1),
                                                                TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                                                TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote),
                                                                           SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END());
                                } else {
@@ -821,6 +832,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
                                                                TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
                                                                SIPTAG_CONTENT_TYPE_STR("application/sdp"),
                                                                SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                                                TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote),
                                                                           SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END());
                                }
@@ -950,13 +962,13 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
                        tech_pvt->session_refresher = nua_no_refresher;
                }
 
-
                if (sofia_use_soa(tech_pvt)) {
                        nua_respond(tech_pvt->nh, SIP_200_OK,
                                                NUTAG_AUTOANSWER(0),
                                                TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
                                                TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
                                                TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
+                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                                NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
                                                NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
                                                NUTAG_UPDATE_REFRESH(tech_pvt->update_refresher),
@@ -977,6 +989,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
                                                TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
                                                TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
                                                TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
+                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                                NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
                                                NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
                                                NUTAG_UPDATE_REFRESH(tech_pvt->update_refresher),
@@ -1399,10 +1412,12 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                        char *xdest;
 
                        if (msg->string_arg) {
+                               const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
                                nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
                                                   NUTAG_SUBSTATE(nua_substate_terminated),
                                                   SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
                                                   SIPTAG_PAYLOAD_STR(msg->string_arg),
+                                                  TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                                   SIPTAG_EVENT_STR("refer"), TAG_END());
                                goto end;
                        }
@@ -1412,6 +1427,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
 
                        if (event && uuid) {
                                char payload_str[255] = "SIP/2.0 403 Forbidden\r\n";
+                               const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
                                if (msg->numeric_arg) {
                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
                                                        "%s Completing blind transfer with success\n", switch_channel_get_name(channel));
@@ -1437,6 +1453,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                                   NUTAG_SUBSTATE(nua_substate_terminated),
                                                   SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
                                                   SIPTAG_PAYLOAD_STR(payload_str),
+                                                  TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                                   SIPTAG_EVENT_STR(event), TAG_END());
 
 
@@ -1508,6 +1525,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_HEADER_PREFIX);
                char ref_to[1024] = "";
                const char *var;
+               const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
 
                if (!strcasecmp(msg->string_arg, "sip:")) {
                        const char *format = strchr(tech_pvt->profile->sipip, ':') ? "sip:%s@[%s]" : "sip:%s@%s";
@@ -1519,6 +1537,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
 
                nua_refer(tech_pvt->nh, SIPTAG_REFER_TO_STR(ref_to), SIPTAG_REFERRED_BY_STR(tech_pvt->contact_url),
                                  TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
+                                 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                  TAG_END());
 
                if (msg->string_array_arg[0]) {
@@ -1570,18 +1589,23 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                        }
 
                        if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) {
+                               const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
+
                                if (sofia_use_soa(tech_pvt)) {
                                        nua_respond(tech_pvt->nh, SIP_200_OK,
                                                                SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
                                                                SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
                                                                SOATAG_REUSE_REJECTED(1),
                                                                SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1),
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                                                TAG_END());
                                } else {
                                        nua_respond(tech_pvt->nh, SIP_200_OK,
                                                                NUTAG_MEDIA_ENABLE(0),
                                                                SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
-                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
+                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                               TAG_END());
                                }
                                switch_channel_mark_answered(channel);
                        }
@@ -1629,9 +1653,10 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
        case SWITCH_MESSAGE_INDICATE_T38_DESCRIPTION:
                {
                        switch_t38_options_t *t38_options = switch_channel_get_private(tech_pvt->channel, "t38_options");
+                       const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
 
                        if (!t38_options) {
-                               nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
+                               nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                                goto end_lock;
                        }
 
@@ -1650,7 +1675,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                                                SOATAG_REUSE_REJECTED(1),
                                                                SOATAG_ORDERED_USER(1),
                                                                SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1),
-                                                               TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
+                                                               TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                               TAG_END());
                                } else {
                                        nua_respond(tech_pvt->nh, SIP_200_OK,
                                                                NUTAG_AUTOANSWER(0),
@@ -1658,7 +1685,10 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                                                SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
                                                                SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")),
                                                                SIPTAG_CONTENT_TYPE_STR("application/sdp"),
-                                                               SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
+                                                               SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
+                                                               TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                               TAG_END());
                                }
                                switch_safe_free(extra_headers);
                                sofia_set_flag_locked(tech_pvt, TFLAG_ANS);
@@ -1688,6 +1718,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
        case SWITCH_MESSAGE_INDICATE_3P_NOMEDIA:
                {
                        char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_HEADER_PREFIX);
+                       const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
 
                        switch_channel_clear_flag(tech_pvt->channel, CF_MEDIA_ACK);
                        switch_channel_set_flag(tech_pvt->channel, CF_REQ_MEDIA);
@@ -1698,7 +1729,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                           NUTAG_MEDIA_ENABLE(0),
                                           TAG_IF(msg->string_arg, SIPTAG_CONTENT_TYPE_STR("application/sdp")),
                                           SIPTAG_PAYLOAD_STR(msg->string_arg),
-                                          TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
+                                          TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
+                                          TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                          TAG_END());
 
                        switch_safe_free(extra_headers);
                }
@@ -1706,6 +1739,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
        case SWITCH_MESSAGE_INDICATE_3P_MEDIA:
                {
                        char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_HEADER_PREFIX);
+                       const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
 
                        sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
 
@@ -1716,7 +1750,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                        sofia_glue_clear_soa(session, SWITCH_TRUE);
 
                        nua_invite(tech_pvt->nh, NUTAG_MEDIA_ENABLE(0), SIPTAG_PAYLOAD_STR(""),
-                                          TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
+                                          TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
+                                          TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                          TAG_END());
 
                        switch_safe_free(extra_headers);
                }
@@ -1785,10 +1821,13 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
                                                                  "Operation not permitted on an inbound non-answered call leg!\n");
                        } else {
+                               const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
                                full_to = switch_str_nil(switch_channel_get_variable(channel, "sip_full_to"));
                                nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active),
                                                   TAG_IF((full_to), SIPTAG_TO_STR(full_to)),SIPTAG_SUBSCRIPTION_STATE_STR("active"),
-                                                  SIPTAG_EVENT_STR(event), TAG_END());
+                                                  SIPTAG_EVENT_STR(event), 
+                                                  TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                  TAG_END());
                        }
 
                }
@@ -1797,6 +1836,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                {
                        char ct[256] = "text/plain";
                        int ok = 0;
+                       const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
 
                        if (!zstr(msg->string_array_arg[3]) && !strcmp(msg->string_array_arg[3], tech_pvt->caller_profile->uuid)) {
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Not sending message back to sender\n");
@@ -1823,10 +1863,11 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                }
 
                                nua_message(tech_pvt->nh,
-                                                SIPTAG_CONTENT_TYPE_STR(ct),
-                                                TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
-                                                TAG_IF(pl, SIPTAG_PAYLOAD_STR(pl)),
-                                                TAG_END());
+                                                       SIPTAG_CONTENT_TYPE_STR(ct),
+                                                       TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
+                                                       TAG_IF(pl, SIPTAG_PAYLOAD_STR(pl)),
+                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                       TAG_END());
                        } else {
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
                                                                  "%s send_message is not supported.\n", switch_channel_get_name(channel));
@@ -1837,6 +1878,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                {
                        char ct[256] = "freeswitch/data";
                        int ok = 0;
+                       const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
 
                        if (switch_stristr("send_info", tech_pvt->x_freeswitch_support_remote)) {
                                ok = 1;
@@ -1863,6 +1905,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                                 TAG_IF(!zstr(headers), SIPTAG_HEADER_STR(headers)),
                                                 TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
                                                 TAG_IF(pl, SIPTAG_PAYLOAD_STR(pl)),
+                                                TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                                 TAG_END());
 
                                switch_safe_free(headers);
@@ -1905,6 +1948,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
 
                        if (to_user && to_host && from_user && from_host && call_id && to_tag && from_tag) {
                                char in[512] = "", out[1536] = "";
+                               const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
 
                                switch_snprintf(in, sizeof(in), "%s;to-tag=%s;from-tag=%s", call_id, to_tag, from_tag);
                                switch_url_encode(in, out, sizeof(out));
@@ -1912,7 +1956,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                ref_to = switch_mprintf("<sip:%s@%s?Replaces=%s>", to_user, to_host, out);
                                ref_by = switch_mprintf("<sip:%s@%s>", from_user, from_host);
 
-                               nua_refer(tech_pvt->nh, SIPTAG_REFER_TO_STR(ref_to), SIPTAG_REFERRED_BY_STR(ref_by), TAG_END());
+                               nua_refer(tech_pvt->nh, SIPTAG_REFER_TO_STR(ref_to), SIPTAG_REFERRED_BY_STR(ref_by), 
+                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), 
+                                               TAG_END());
                                switch_safe_free(ref_to);
                                switch_safe_free(ref_by);
                        }
@@ -1937,6 +1983,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                const char *allow = switch_channel_get_variable(tech_pvt->channel, "sip_allow");
                                switch_event_t *event;
                                int update_allowed = 0;
+                               const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
 
                                check_decode(name, tech_pvt->session);
 
@@ -1970,7 +2017,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
 
                                                        nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/update_display"),
                                                                         TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
-                                                                        TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
+                                                                        TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
+                                                                        TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                        TAG_END());
                                                } else if (ua && switch_stristr("snom", ua)) {
                                                        const char *ver_str = NULL;
                                                        int version = 0;
@@ -2025,7 +2074,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                                                           TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
                                                                           TAG_IF(!zstr(tech_pvt->route_uri), NUTAG_PROXY(tech_pvt->route_uri)),
                                                                           TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
-                                                                          TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
+                                                                          TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
+                                                                          TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                          TAG_END());
                                                }
 
                                                tech_pvt->last_sent_callee_id_name = switch_core_session_strdup(tech_pvt->session, name);
@@ -2070,11 +2121,15 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                if (!zstr(msg->string_arg)) {
                                        char message[256] = "";
                                        const char *ua = switch_channel_get_variable(tech_pvt->channel, "sip_user_agent");
+                                       const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
 
                                        if (ua && switch_stristr("snom", ua)) {
                                                snprintf(message, sizeof(message), "From:\r\nTo: \"%s\" %s\r\n", msg->string_arg, tech_pvt->caller_profile->destination_number);
                                                nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
-                                                                TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), SIPTAG_PAYLOAD_STR(message), TAG_END());
+                                                                TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
+                                                                SIPTAG_PAYLOAD_STR(message),
+                                                                TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                TAG_END());
                                        } else if (ua && switch_stristr("polycom", ua)) {
                                                snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" <%s>", msg->string_arg, tech_pvt->caller_profile->destination_number);
                                                nua_update(tech_pvt->nh,
@@ -2083,7 +2138,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                                                   NUTAG_UPDATE_REFRESH(tech_pvt->update_refresher),
                                                                   TAG_IF(!zstr(tech_pvt->route_uri), NUTAG_PROXY(tech_pvt->route_uri)),
                                                                   TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
-                                                                  TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
+                                                                  TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
+                                                                  TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                  TAG_END());
                                        }
                                }
                        }
@@ -2183,6 +2240,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                break;
        case SWITCH_MESSAGE_INDICATE_RESPOND:
                {
+                       const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
                        if (switch_channel_test_flag(tech_pvt->channel, CF_AWAITING_STREAM_CHANGE)) {
                                switch_channel_clear_flag(tech_pvt->channel, CF_AWAITING_STREAM_CHANGE);
 
@@ -2195,12 +2253,17 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                                                SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
                                                                SOATAG_REUSE_REJECTED(1),
                                                                SOATAG_AUDIO_AUX("cn telephone-event"),
-                                                               TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
+                                                               TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                               TAG_END());
                                } else {
                                        nua_respond(tech_pvt->nh, SIP_200_OK,
                                                                NUTAG_MEDIA_ENABLE(0),
                                                                SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
-                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
+                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"),
+                                                               SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                               TAG_END());
                                }
                        }
 
@@ -2245,8 +2308,12 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
 
                                if (tech_pvt->proxy_refer_uuid) {
                                        if (tech_pvt->proxy_refer_msg) {
-                                               nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason), SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
-                                                                       SIPTAG_EXPIRES_STR("60"), NUTAG_WITH_THIS_MSG(tech_pvt->proxy_refer_msg), TAG_END());
+                                               nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason),
+                                                                       SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
+                                                                       SIPTAG_EXPIRES_STR("60"),
+                                                                       NUTAG_WITH_THIS_MSG(tech_pvt->proxy_refer_msg),
+                                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                       TAG_END());
                                                msg_ref_destroy(tech_pvt->proxy_refer_msg);
                                                tech_pvt->proxy_refer_msg = NULL;
                                        }
@@ -2296,13 +2363,17 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                                                                        SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
                                                                                        SOATAG_REUSE_REJECTED(1),
                                                                                        SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1),
-                                                                                       TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
+                                                                                       TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
+                                                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                                       TAG_END());
                                                        } else {
                                                                nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason), SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
                                                                                        NUTAG_MEDIA_ENABLE(0),
                                                                                        SIPTAG_CONTENT_TYPE_STR("application/sdp"),
                                                                                        SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
-                                                                                       TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
+                                                                                       TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
+                                                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                                       TAG_END());
                                                        }
 
                                                        if (sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY) && sofia_test_flag(tech_pvt, TFLAG_3PCC)) {
@@ -2336,8 +2407,11 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot respond.\n");
                                                                }
                                                        } else {
-                                                               nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason), SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
-                                                                                       TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
+                                                               nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason),
+                                                                                       SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
+                                                                                       TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
+                                                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                                       TAG_END());
                                                        }
 
                                                }
@@ -2353,13 +2427,17 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                        char *extra_header = sofia_glue_get_extra_headers(channel, SOFIA_SIP_PROGRESS_HEADER_PREFIX);
                        const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full");
                        char *cid = generate_pai_str(tech_pvt);
+                       const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
+
                        nua_respond(tech_pvt->nh, SIP_180_RINGING,
                                                SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
                                                TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
                                                TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
                                                TAG_IF(!zstr(extra_header), SIPTAG_HEADER_STR(extra_header)),
                                                TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote),
-                                                          SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END());
+                                                          SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)),
+                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                               TAG_END());
                }
                break;
        case SWITCH_MESSAGE_INDICATE_ACKNOWLEDGE_CALL:
@@ -2378,6 +2456,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                char *extra_header = sofia_glue_get_extra_headers(channel, SOFIA_SIP_PROGRESS_HEADER_PREFIX);
                                const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full");
                                char *cid = generate_pai_str(tech_pvt);
+                               const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
 
                                /* Set sip_to_tag to local tag for inbound channels. */
                                if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
@@ -2398,7 +2477,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                                                TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
                                                                TAG_IF(!zstr(extra_header), SIPTAG_HEADER_STR(extra_header)),
                                                                TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote),
-                                                                          SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END());
+                                                                          SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)),
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                               TAG_END());
                                        break;
 
                                case SWITCH_RING_READY_RINGING:
@@ -2410,7 +2491,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                                                TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
                                                                TAG_IF(!zstr(extra_header), SIPTAG_HEADER_STR(extra_header)),
                                                                TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote),
-                                                                          SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END());
+                                                                          SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)),
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                               TAG_END());
 
                                        break;
                                }
@@ -2528,6 +2611,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) {
                                        char *extra_header = sofia_glue_get_extra_headers(channel, SOFIA_SIP_PROGRESS_HEADER_PREFIX);
                                        char *cid = NULL;
+                                       const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
 
                                        cid = generate_pai_str(tech_pvt);
 
@@ -2556,7 +2640,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                                                        TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
                                                                        TAG_IF(!zstr(extra_header), SIPTAG_HEADER_STR(extra_header)),
                                                                        TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote),
-                                                                                  SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END());
+                                                                                  SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)),
+                                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                       TAG_END());
                                        } else {
                                                nua_respond(tech_pvt->nh,
                                                                        send_sip_code, p_send_sip_msg,
@@ -2570,7 +2656,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                                                        TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
                                                                        TAG_IF(!zstr(extra_header), SIPTAG_HEADER_STR(extra_header)),
                                                                        TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote),
-                                                                                  SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END());
+                                                                                  SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)),
+                                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                       TAG_END());
                                        }
                                        switch_safe_free(extra_header);
                                }
@@ -2583,7 +2671,17 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                        switch_t38_options_t *t38_options = switch_channel_get_private(channel, "t38_options");
 
                        if (!t38_options) {
-                               nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
+                               const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
+
+                               nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
+                       }
+               }
+               break;
+
+       case SWITCH_MESSAGE_INDICATE_SESSION_ID:
+               {
+                       if (sofia_test_pflag(tech_pvt->profile, PFLAG_RFC7989_SESSION_ID) && switch_channel_test_flag(channel, CF_ANSWERED)) {
+                               sofia_glue_do_invite(session);
                        }
                }
                break;
@@ -5198,7 +5296,8 @@ static int notify_csta_callback(void *pArg, int argc, char **argv, char **column
 
        nua_notify(nh, NUTAG_NEWSUB(1),
                           TAG_IF(dst->route_uri, NUTAG_PROXY(route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)), TAG_IF(call_id, SIPTAG_CALL_ID_STR(call_id)),
-                          SIPTAG_EVENT_STR("as-feature-event"), SIPTAG_CONTENT_TYPE_STR(ct), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), SIPTAG_CSEQ(cseq), TAG_END());
+                          SIPTAG_EVENT_STR("as-feature-event"), SIPTAG_CONTENT_TYPE_STR(ct), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), SIPTAG_CSEQ(cseq), 
+                          TAG_END());
 
 
 
@@ -5346,7 +5445,8 @@ void general_event_handler(switch_event_t *event)
                                                           NUTAG_NEWSUB(1), TAG_IF(sip_sub_st, SIPTAG_SUBSCRIPTION_STATE_STR(sip_sub_st)),
                                                           TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)), TAG_IF(call_id, SIPTAG_CALL_ID_STR(call_id)),
                                                           SIPTAG_EVENT_STR(es), TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(ct)), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)),
-                                                          TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
+                                                          TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), 
+                                                          TAG_END());
 
                                        switch_safe_free(route_uri);
                                        sofia_glue_free_destination(dst);
@@ -5399,7 +5499,8 @@ void general_event_handler(switch_event_t *event)
                                                           NUTAG_NEWSUB(1), SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
                                                           TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
                                                           SIPTAG_EVENT_STR(es), TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(ct)), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)),
-                                                          TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
+                                                          TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
+                                                          TAG_END());
 
 
                                        switch_safe_free(route_uri);
@@ -5417,9 +5518,12 @@ void general_event_handler(switch_event_t *event)
 
                                if ((session = switch_core_session_locate(uuid))) {
                                        if ((tech_pvt = switch_core_session_get_private(session))) {
+                                               const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
                                                nua_notify(tech_pvt->nh,
                                                                   NUTAG_NEWSUB(1), SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
-                                                                  SIPTAG_EVENT_STR(es), SIPTAG_CONTENT_TYPE_STR(ct), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), TAG_END());
+                                                                  SIPTAG_EVENT_STR(es), SIPTAG_CONTENT_TYPE_STR(ct), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)),
+                                                                  TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                  TAG_END());
                                        }
                                        switch_core_session_rwunlock(session);
                                }
@@ -5614,9 +5718,13 @@ void general_event_handler(switch_event_t *event)
 
                                if ((session = switch_core_session_locate(uuid))) {
                                        if ((tech_pvt = switch_core_session_get_private(session))) {
+                                               const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
+
                                                nua_message(tech_pvt->nh,
                                                                        SIPTAG_CONTENT_TYPE_STR(ct), SIPTAG_PAYLOAD_STR(body),
-                                                                       TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), TAG_IF(!zstr(subject), SIPTAG_SUBJECT_STR(subject)), TAG_END());
+                                                                       TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), TAG_IF(!zstr(subject), SIPTAG_SUBJECT_STR(subject)),
+                                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                       TAG_END());
                                        }
                                        switch_core_session_rwunlock(session);
                                }
index de44aac2838c7365bac6fafffe54f14ddee4d960..5e5feb2d6d7baa27f45361c0147e8a35a9952070 100644 (file)
@@ -192,6 +192,7 @@ struct sofia_private {
        int is_call;
        int is_static;
        switch_time_t ping_sent;
+       char *rfc7989_uuid;
 };
 
 #define set_param(ptr,val) if (ptr) {free(ptr) ; ptr = NULL;} if (val) {ptr = strdup(val);}
@@ -310,6 +311,8 @@ typedef enum {
        PFLAG_FIRE_BYE_RESPONSE_EVENTS,
        PFLAG_AUTO_INVITE_100,
        PFLAG_UPDATE_REFRESHER,
+       PFLAG_RFC7989_SESSION_ID,
+       PFLAG_RFC7989_FORCE_OLD,
        PFLAG_AUTH_REQUIRE_USER,
        PFLAG_AUTH_CALLS_ACL_ONLY,
        PFLAG_USE_PORT_FOR_ACL_CHECK,
@@ -790,6 +793,7 @@ struct sofia_profile {
        int bind_attempt_interval;
        char *proxy_notify_events;
        char *proxy_info_content_types;
+       char *rfc7989_filter;
        char *acl_inbound_x_token_header;
        char *acl_proxy_x_token_header;
 };
@@ -989,6 +993,13 @@ void launch_sofia_profile_thread(sofia_profile_t *profile);
 
 switch_status_t sofia_presence_chat_send(switch_event_t *message_event);
 
+#define RFC7989_SESSION_UUID_LEN 32
+#define RFC7989_SESSION_UUID_NULL "00000000000000000000000000000000"
+
+int sofia_glue_is_valid_session_id(const char *session_id);
+void sofia_glue_store_session_id(switch_core_session_t *session, sofia_profile_t *profile, sip_t const *sip, switch_bool_t is_reply);
+char *sofia_glue_session_id_header(switch_core_session_t *session, sofia_profile_t *profile);
+
 /*
  * \brief Sets the "ep_codec_string" channel variable, parsing r_sdp and taing codec_string in consideration
  * \param channel Current channel
index 24c5a2d74957ffbddd66a2acbd18a6ed41294582..ef6e49a2a5dd218ce4d954caeb2e2521056aba48 100644 (file)
@@ -610,6 +610,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
        sofia_gateway_subscription_t *gw_sub_ptr;
        int sub_state;
        sofia_gateway_t *gateway = NULL;
+       const char *session_id_header = sofia_glue_session_id_header(session, profile);
 
        tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END());
 
@@ -621,7 +622,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
        /* Automatically return a 200 OK for Event: keep-alive */
        if (!strcasecmp(sip->sip_event->o_type, "keep-alive")) {
                /* XXX MTK - is this right? in this case isn't sofia is already sending a 200 itself also? */
-               nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+               nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                goto end;
        }
 
@@ -717,7 +718,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
                                }
                        }
                }
-               nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+               nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
        }
 
        /* if no session, assume it could be an incoming notify from a gateway subscription */
@@ -738,11 +739,14 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
                                nua_notify(other_tech_pvt->nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active),
                                                        TAG_IF((full_to), SIPTAG_TO_STR(full_to)), SIPTAG_SUBSCRIPTION_STATE_STR("active"),
                                                        SIPTAG_EVENT_STR(sip->sip_event->o_type), TAG_IF(!zstr(unknown), SIPTAG_HEADER_STR(unknown)),
-                                                       TAG_IF(!zstr(pl), SIPTAG_PAYLOAD_STR(pl)), TAG_END());
+                                                       TAG_IF(!zstr(pl), SIPTAG_PAYLOAD_STR(pl)), 
+                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                       TAG_END());
                                switch_safe_free(unknown);
                                switch_core_session_rwunlock(other_session);
                        }
-                       nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+                       nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
+                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                        goto end;
                }
                /* make sure we have a proper "talk" event */
@@ -754,7 +758,8 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
                        switch_channel_answer(channel);
                        switch_channel_set_variable(channel, "auto_answer_destination", switch_channel_get_variable(channel, "destination_number"));
                        switch_ivr_session_transfer(session, "auto_answer", NULL, NULL);
-                       nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+                       nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
+                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                        goto end;
                }
        }
@@ -841,7 +846,8 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
 
        if (sip && sip->sip_event && sip->sip_event->o_type && !strcasecmp(sip->sip_event->o_type, "message-summary")) {
                /* unsolicited mwi, just say ok */
-               nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+               nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
+                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),  TAG_END());
 
                if (sofia_test_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY)) {
                        const char *mwi_status = NULL;
@@ -890,7 +896,8 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
                }
 
        } else {
-               nua_respond(nh, 481, "Subscription Does Not Exist", NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+               nua_respond(nh, 481, "Subscription Does Not Exist", NUTAG_WITH_THIS_MSG(de->data->e_msg),
+                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
        }
 
   end:
@@ -942,6 +949,7 @@ void sofia_handle_sip_i_bye(switch_core_session_t *session, int status,
        char *extra_headers;
        const char *call_info = NULL;
        const char *vval = NULL;
+       const char *session_id_header = sofia_glue_session_id_header(session, profile);
 #ifdef MANUAL_BYE
        int cause;
        char st[80] = "";
@@ -1078,7 +1086,8 @@ void sofia_handle_sip_i_bye(switch_core_session_t *session, int status,
 
        switch_channel_hangup(channel, cause);
        nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
-                               TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
+                               TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
+                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
 
        switch_safe_free(extra_headers);
 
@@ -1385,6 +1394,7 @@ static void tech_send_ack(nua_handle_t *nh, private_object_t *tech_pvt, const ch
        const char *invite_full_from = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_from");
        const char *invite_full_to = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_to");
        int soa = sofia_use_soa(tech_pvt);
+       const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
 
        if (sofia_test_pflag(tech_pvt->profile, PFLAG_TRACK_CALLS)) {
                const char *invite_full_via = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_via");
@@ -1402,6 +1412,7 @@ static void tech_send_ack(nua_handle_t *nh, private_object_t *tech_pvt, const ch
                                TAG_IF(r_sdp && !soa, SIPTAG_CONTENT_TYPE_STR("application/sdp")),
                                TAG_IF(r_sdp && !soa, SIPTAG_PAYLOAD_STR(r_sdp)),
                                TAG_IF(r_sdp && !soa, NUTAG_MEDIA_ENABLE(0)),
+                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                TAG_END());
        } else {
                nua_ack(nh,
@@ -1414,6 +1425,7 @@ static void tech_send_ack(nua_handle_t *nh, private_object_t *tech_pvt, const ch
                                TAG_IF(r_sdp && !soa, SIPTAG_CONTENT_TYPE_STR("application/sdp")),
                                TAG_IF(r_sdp && !soa, SIPTAG_PAYLOAD_STR(r_sdp)),
                                TAG_IF(r_sdp && !soa, NUTAG_MEDIA_ENABLE(0)),
+                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                TAG_END());
        }
 
@@ -1671,6 +1683,7 @@ static void our_sofia_event_callback(nua_event_t event,
                {
                        if (channel && sip) {
                                const char *r_sdp = NULL;
+                               sofia_glue_store_session_id(session, profile, sip, 0);
 
                                if (sip->sip_payload && sip->sip_payload->pl_data) {
                                        if (sofia_test_flag(tech_pvt, TFLAG_PASS_ACK)) {
@@ -5299,6 +5312,20 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
                                                } else {
                                                        sofia_clear_pflag(profile, PFLAG_UPDATE_REFRESHER);
                                                }
+                                       } else if (!strcasecmp(var, "rfc-7989")) {
+                                               if (switch_true(val)) {
+                                                       sofia_set_pflag(profile, PFLAG_RFC7989_SESSION_ID);
+                                               } else {
+                                                       sofia_clear_pflag(profile, PFLAG_RFC7989_SESSION_ID);
+                                               }
+                                       } else if (!strcasecmp(var, "rfc-7989-filter")) {
+                                               profile->rfc7989_filter = switch_core_strdup(profile->pool, val);
+                                       } else if (!strcasecmp(var, "rfc-7989-force-old")) {
+                                               if (switch_true(val)) {
+                                                       sofia_set_pflag(profile, PFLAG_RFC7989_FORCE_OLD);
+                                               } else {
+                                                       sofia_clear_pflag(profile, PFLAG_RFC7989_FORCE_OLD);
+                                               }
                                        } else if (!strcasecmp(var, "manage-shared-appearance")) {
                                                if (switch_true(val)) {
                                                        sofia_set_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE);
@@ -6616,6 +6643,8 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
 
                        switch_channel_set_flag(channel, CF_MEDIA_ACK);
 
+                       sofia_glue_store_session_id(session, profile, sip, 1);
+
                        if ((x_freeswitch_support = sofia_glue_get_unknown_header(sip, "X-FS-Support"))) {
                                tech_pvt->x_freeswitch_support_remote = switch_core_session_strdup(session, x_freeswitch_support);
                        }
@@ -7222,6 +7251,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
        switch_event_t *s_event = NULL;
        char *p;
        char *patched_sdp = NULL;
+       const char *session_id_header = sofia_glue_session_id_header(session, profile);
 
        tl_gets(tags,
                        NUTAG_CALLSTATE_REF(ss_state),
@@ -7389,6 +7419,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                           TAG_IF((full_to), SIPTAG_TO_STR(full_to)),
                                           SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
                                           SIPTAG_EVENT_STR("talk"),
+                                          TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                           TAG_END());
                }
        }
@@ -7501,7 +7532,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                        switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA");
                                        switch_core_media_patch_sdp(tech_pvt->session);
                                        if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
-                                               nua_respond(nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
+                                               nua_respond(nh, SIP_488_NOT_ACCEPTABLE, 
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                                                switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
                                        } else{
                                                switch_channel_mark_pre_answered(channel);
@@ -7510,7 +7542,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                } else {
                                        if (sofia_media_tech_media(tech_pvt, (char *) r_sdp) != SWITCH_STATUS_SUCCESS) {
                                                switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR");
-                                               nua_respond(nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
+                                               nua_respond(nh, SIP_488_NOT_ACCEPTABLE, 
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),TAG_END());
                                                switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
                                        }
                                }
@@ -7543,7 +7576,6 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                        }
 
                        if (switch_channel_test_flag(channel, CF_3P_NOMEDIA_REQUESTED)) {
-
                                if (switch_channel_test_flag(channel, CF_3P_NOMEDIA_REQUESTED_BLEG)) {
                                        switch_core_session_t *other_session;
 
@@ -7565,6 +7597,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                                                SOATAG_RTP_SELECT(1),
                                                                                SOATAG_AUDIO_AUX("cn telephone-event"),
                                                                                TAG_IF(sofia_test_pflag(other_tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
+                                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                                                                TAG_END());
                                                        } else {
                                                                nua_ack(other_tech_pvt->nh,
@@ -7574,12 +7607,14 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                                                TAG_IF(r_sdp, SIPTAG_CONTENT_TYPE_STR("application/sdp")),
                                                                                TAG_IF(r_sdp, SIPTAG_PAYLOAD_STR(r_sdp)),
                                                                                SOATAG_AUDIO_AUX("cn telephone-event"),
+                                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), 
                                                                                TAG_END());
                                                        }
 
                                                        nua_ack(tech_pvt->nh,
                                                                        TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
                                                                        SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
+                                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), 
                                                                        TAG_END());
 
                                                }
@@ -7606,7 +7641,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
 
                                if (!match) {
                                        if (switch_channel_get_state(channel) != CS_NEW) {
-                                               nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
+                                               nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, 
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),TAG_END());
                                        }
                                } else {
                                        switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
@@ -7632,6 +7668,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                                SOATAG_RTP_SELECT(1),
                                                                SOATAG_AUDIO_AUX("cn telephone-event"),
                                                                TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                                                TAG_END());
                                        } else {
                                                nua_ack(tech_pvt->nh,
@@ -7641,6 +7678,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                                TAG_IF(tech_pvt->mparams.local_sdp_str, SIPTAG_CONTENT_TYPE_STR("application/sdp")),
                                                                TAG_IF(tech_pvt->mparams.local_sdp_str, SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str)),
                                                                SOATAG_AUDIO_AUX("cn telephone-event"),
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                                                TAG_END());
                                        }
 
@@ -7698,7 +7736,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
                                                                          "Other leg already handling a reinvite, so responding with 491\n");
 
-                                       nua_respond(tech_pvt->nh, SIP_491_REQUEST_PENDING, TAG_END());
+                                       nua_respond(tech_pvt->nh, SIP_491_REQUEST_PENDING, 
+                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                                        sofia_glue_do_invite(session);
                                        goto done;
                                }
@@ -7747,7 +7786,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                if (switch_channel_get_state(channel) == CS_NEW) {
                                                        switch_channel_set_state(channel, CS_INIT);
                                                } else {
-                                                       nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END());
+                                                       nua_respond(tech_pvt->nh, SIP_200_OK, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                                                }
                                                sofia_set_flag(tech_pvt, TFLAG_SDP);
                                                if (replaces_str) {
@@ -7825,12 +7864,16 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                                                SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
                                                                                SOATAG_REUSE_REJECTED(1),
                                                                                SOATAG_AUDIO_AUX("cn telephone-event"),
-                                                                               TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
+                                                                               TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
+                                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                               TAG_END());
                                                } else {
                                                        nua_respond(tech_pvt->nh, SIP_200_OK,
                                                                                NUTAG_MEDIA_ENABLE(0),
                                                                                SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
-                                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
+                                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
+                                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                               TAG_END());
                                                }
                                        }
                                } else if (sofia_test_pflag(profile, PFLAG_3PCC_PROXY)) {
@@ -7897,12 +7940,16 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                                SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
                                                                SOATAG_REUSE_REJECTED(1),
                                                                SOATAG_AUDIO_AUX("cn telephone-event"),
-                                                               TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
+                                                               TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                               TAG_END());
                                } else {
                                        nua_respond(tech_pvt->nh, SIP_200_OK,
                                                                NUTAG_MEDIA_ENABLE(0),
                                                                SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
-                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
+                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                               TAG_END());
                                }
                        }
 
@@ -7945,11 +7992,12 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                if (r_sdp) {
                        const char *var;
                        uint8_t match = 0, is_ok = 1, is_t38 = 0;
+
                        tech_pvt->mparams.hold_laps = 0;
 
                                if ((var = switch_channel_get_variable(channel, "sip_ignore_reinvites")) && switch_true(var)) {
                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Ignoring Re-invite\n");
-                                       nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END());
+                                       nua_respond(tech_pvt->nh, SIP_200_OK, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                                        goto done;
                                }
 
@@ -7962,7 +8010,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                        if ((sofia_test_media_flag(profile, SCMF_DISABLE_HOLD)
                                                 || ((var = switch_channel_get_variable(channel, "rtp_disable_hold")) && switch_true(var)))
                                                && ((switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp) || switch_stristr("inactive", r_sdp)) || tech_pvt->mparams.hold_laps)) {
-                                               nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END());
+                                               nua_respond(tech_pvt->nh, SIP_200_OK, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
 
                                                if (tech_pvt->mparams.hold_laps) {
                                                        tech_pvt->mparams.hold_laps = 0;
@@ -8024,12 +8072,16 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                                                                SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
                                                                                                SOATAG_REUSE_REJECTED(1),
                                                                                                SOATAG_AUDIO_AUX("cn telephone-event"),
-                                                                                               TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
+                                                                                               TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
+                                                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                                               TAG_END());
                                                                } else {
                                                                        nua_respond(tech_pvt->nh, SIP_200_OK,
                                                                                                NUTAG_MEDIA_ENABLE(0),
                                                                                                SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
-                                                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
+                                                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
+                                                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                                               TAG_END());
                                                                }
 
                                                                switch_channel_set_flag(channel, CF_PROXY_MODE);
@@ -8046,7 +8098,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                        switch_core_media_proxy_remote_addr(session, r_sdp);
 
                                                        if ((tech_pvt->profile->mndlb & SM_NDLB_NEVER_PATCH_REINVITE)) {
-                                                               nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END());
+                                                               nua_respond(tech_pvt->nh, SIP_200_OK, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "NOT proxying re-invite.\n");
                                                                switch_core_session_rwunlock(other_session);
                                                                goto done;
@@ -8058,7 +8110,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                if (sofia_test_flag(other_tech_pvt, TFLAG_REINVITED)) {
                                                        /* The other leg won the reinvite race */
                                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Other leg already handling reinvite, so responding with 491\n");
-                                                       nua_respond(tech_pvt->nh, SIP_491_REQUEST_PENDING, TAG_END());
+                                                       nua_respond(tech_pvt->nh, SIP_491_REQUEST_PENDING, 
+                                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                                                        switch_core_session_rwunlock(other_session);
                                                        goto done;
                                                }
@@ -8127,7 +8180,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
 
                                                                if (!match) {
                                                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reinvite Codec Error!\n");
-                                                                       nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
+                                                                       nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE,
+                                                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                                               TAG_END());
                                                                        switch_core_session_rwunlock(other_session);
                                                                        goto done;
                                                                }
@@ -8176,12 +8231,16 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                                                                SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
                                                                                                SOATAG_REUSE_REJECTED(1),
                                                                                                SOATAG_AUDIO_AUX("cn telephone-event"),
-                                                                                               TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
+                                                                                               TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
+                                                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                                               TAG_END());
                                                                } else {
                                                                        nua_respond(tech_pvt->nh, SIP_200_OK,
                                                                                                NUTAG_MEDIA_ENABLE(0),
                                                                                                SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
-                                                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
+                                                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
+                                                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                                               TAG_END());
                                                                }
                                                                switch_core_session_rwunlock(other_session);
                                                                goto done;
@@ -8198,12 +8257,16 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                                                SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
                                                                                SOATAG_REUSE_REJECTED(1),
                                                                                SOATAG_AUDIO_AUX("cn telephone-event"),
-                                                                               TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
+                                                                               TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
+                                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                               TAG_END());
                                                } else {
                                                        nua_respond(tech_pvt->nh, SIP_200_OK,
                                                                                NUTAG_MEDIA_ENABLE(0),
                                                                                SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
-                                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
+                                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
+                                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                               TAG_END());
                                                }
                                                goto done;
                                        }
@@ -8216,7 +8279,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
 
 
                                        if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
-                                               nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END());
+                                               nua_respond(tech_pvt->nh, SIP_200_OK, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                                                goto done;
                                        }
 
@@ -8240,7 +8303,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Processing updated SDP\n");
                                        } else {
                                                if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
-                                                       nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END());
+                                                       nua_respond(tech_pvt->nh, SIP_200_OK, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                                                        goto done;
                                                }
 
@@ -8264,12 +8327,16 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                                                SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
                                                                                SOATAG_REUSE_REJECTED(1),
                                                                                SOATAG_AUDIO_AUX("cn telephone-event"),
-                                                                               TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
+                                                                               TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
+                                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                               TAG_END());
                                                } else {
                                                        nua_respond(tech_pvt->nh, SIP_200_OK,
                                                                                NUTAG_MEDIA_ENABLE(0),
                                                                                SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
-                                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
+                                                                               SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
+                                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                               TAG_END());
                                                }
                                        }
 
@@ -8278,7 +8345,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                switch_event_fire(&s_event);
                                        }
                                } else {
-                                       nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
+                                       nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE,
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                               TAG_END());
                                }
                        }
                break;
@@ -8371,7 +8440,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                }
 
                                if (!is_ok) {
-                                       nua_respond(nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
+                                       nua_respond(nh, SIP_488_NOT_ACCEPTABLE, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                                        switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
                                }
                        }
@@ -8553,6 +8622,7 @@ typedef struct {
        char *bridge_to_uuid;
        switch_event_t *vars;
        switch_memory_pool_t *pool;
+       sofia_profile_t *profile;
 } nightmare_xfer_helper_t;
 
 void *SWITCH_THREAD_FUNC nightmare_xfer_thread_run(switch_thread_t *thread, void *obj)
@@ -8571,6 +8641,7 @@ void *SWITCH_THREAD_FUNC nightmare_xfer_thread_run(switch_thread_t *thread, void
                if ((session = switch_core_session_locate(nhelper->reply_uuid))) {
                        private_object_t *tech_pvt = switch_core_session_get_private(session);
                        switch_channel_t *channel_a = switch_core_session_get_channel(session);
+                       const char *session_id_header = sofia_glue_session_id_header(session, nhelper->profile);
 
                        if ((status = switch_ivr_originate(NULL, &tsession, &cause, nhelper->exten_with_params, timeout, NULL, NULL, NULL,
                                                                                           switch_channel_get_caller_profile(channel_a), nhelper->vars, SOF_NONE, NULL, NULL)) == SWITCH_STATUS_SUCCESS) {
@@ -8602,7 +8673,9 @@ void *SWITCH_THREAD_FUNC nightmare_xfer_thread_run(switch_thread_t *thread, void
                        nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
                                           NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
                                           SIPTAG_PAYLOAD_STR(status == SWITCH_STATUS_SUCCESS ? "SIP/2.0 200 OK\r\n" :
-                                                                                 "SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(nhelper->event), TAG_END());
+                                                                                 "SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(nhelper->event), 
+                                          TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                          TAG_END());
 
                        switch_core_session_rwunlock(session);
                }
@@ -8727,6 +8800,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
        nightmare_xfer_helper_t *nightmare_xfer_helper;
        switch_memory_pool_t *npool;
        switch_event_t *event = NULL;
+       const char *session_id_header = sofia_glue_session_id_header(session, profile);
 
        if (!(profile->mflags & MFLAG_REFER)) {
                nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
@@ -8760,7 +8834,8 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
        from = sip->sip_from;
        //to = sip->sip_to;
 
-       nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_EXPIRES_STR("60"), TAG_END());
+       nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_EXPIRES_STR("60"), 
+                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
 
 
        switch_channel_set_variable(tech_pvt->channel, SOFIA_REPLACES_HEADER, NULL);
@@ -8889,6 +8964,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
 
                                                nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
                                                        NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
+                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                                        SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp), TAG_END());
 
                                        } else if (switch_channel_test_flag(channel_b, CF_ORIGINATOR)) {
@@ -8982,6 +9058,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
 
                                                        nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
                                                                           NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"), SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp),
+                                                                          TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                                                           TAG_END());
 
                                                        if (b_tech_pvt && !sofia_test_flag(b_tech_pvt, TFLAG_BYE)) {
@@ -8996,13 +9073,17 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                                                                nua_bye(b_tech_pvt->nh,
                                                                                SIPTAG_CONTACT(SIP_NONE),
                                                                                TAG_IF(!zstr(q850), SIPTAG_REASON_STR(q850)),
-                                                                               TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
+                                                                               TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), 
+                                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                               TAG_END());
 
                                                        }
                                                } else {
                                                        nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
                                                                           NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
-                                                                          SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp), TAG_END());
+                                                                          SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp), 
+                                                                          TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                          TAG_END());
                                                }
 
                                        } else if (br_a && br_b) {
@@ -9081,6 +9162,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                                                switch_channel_set_variable(channel_b, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER");
                                                nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
                                                                   NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"), SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp),
+                                                                  TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                                                   TAG_END());
 
                                                sofia_clear_flag_locked(b_tech_pvt, TFLAG_SIP_HOLD);
@@ -9096,7 +9178,9 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                                                                                          "Cannot transfer channels that are not in a bridge.\n");
                                                        nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
                                                                           NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"), SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"),
-                                                                          SIPTAG_EVENT_STR(etmp), TAG_END());
+                                                                          SIPTAG_EVENT_STR(etmp), 
+                                                                          TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                          TAG_END());
                                                } else {
                                                        switch_core_session_t *t_session, *hup_session;
                                                        switch_channel_t *hup_channel;
@@ -9162,14 +9246,18 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                                                                                   NUTAG_NEWSUB(1),
                                                                                   SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
                                                                                   NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
-                                                                                  SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp), TAG_END());
+                                                                                  SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp), 
+                                                                                  TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                                  TAG_END());
                                                                switch_core_session_rwunlock(t_session);
                                                                switch_channel_hangup(hup_channel, SWITCH_CAUSE_ATTENDED_TRANSFER);
                                                        } else {
                                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session to transfer to not found.\n");
                                                                nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
                                                                                   NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
-                                                                                  SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp), TAG_END());
+                                                                                  SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp), 
+                                                                                  TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                                  TAG_END());
                                                        }
                                                }
                                        }
@@ -9346,6 +9434,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                                                switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, "sip_h_X-FS-Refer-For", br_a);
 
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Good Luck, you'll need it......\n");
+                                               nightmare_xfer_helper->profile = profile;
                                                launch_nightmare_xfer(nightmare_xfer_helper);
 
                                                switch_core_session_rwunlock(a_session);
@@ -9360,6 +9449,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                                        switch_channel_set_variable(channel_a, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER_ERROR");
                                        nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
                                                           NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"), SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp),
+                                                          TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                                           TAG_END());
                                }
                        }
@@ -9413,7 +9503,9 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                                nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
                                                   NUTAG_SUBSTATE(nua_substate_terminated),
                                                   SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
-                                                  SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp), TAG_END());
+                                                  SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp), 
+                                                  TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                  TAG_END());
                        }
 
             if (refer_to->r_url->url_params) {
@@ -9450,7 +9542,9 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                        nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
                                           NUTAG_SUBSTATE(nua_substate_terminated),
                                           SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
-                                          SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp), TAG_END());
+                                          SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp), 
+                                          TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                          TAG_END());
                }
        }
 
@@ -9533,6 +9627,7 @@ switch_status_t sofia_proxy_sip_i_message(nua_t *nua, sofia_profile_t *profile,
                                                                           sofia_dispatch_event_t *de, tagi_t tags[])
 {
        switch_core_session_t *other_session = NULL;
+       const char *session_id_header = sofia_glue_session_id_header(session, profile);
 
        if (session && switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
                if (switch_core_session_compare(session, other_session)) {
@@ -9552,15 +9647,18 @@ switch_status_t sofia_proxy_sip_i_message(nua_t *nua, sofia_profile_t *profile,
                        }
 
                        nua_message(other_tech_pvt->nh,
-                                        TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(su_strdup(other_tech_pvt->nh->nh_home, ct))),
-                                        TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via)),
-                                        TAG_IF(pl, SIPTAG_PAYLOAD_STR(su_strdup(other_tech_pvt->nh->nh_home, pl))),
-                                        TAG_END());
+                                               TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(su_strdup(other_tech_pvt->nh->nh_home, ct))),
+                                               TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via)),
+                                               TAG_IF(pl, SIPTAG_PAYLOAD_STR(su_strdup(other_tech_pvt->nh->nh_home, pl))),
+                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                               TAG_END());
                }
 
                switch_core_session_rwunlock(other_session);
 
-               nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+               nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg),
+                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                       TAG_END());
 
                return SWITCH_STATUS_SUCCESS;
        }
@@ -9572,6 +9670,7 @@ switch_status_t sofia_proxy_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua
                                                                sofia_dispatch_event_t *de, tagi_t tags[])
 {
        switch_core_session_t *other_session = NULL;
+       const char *session_id_header = sofia_glue_session_id_header(session, profile);
 
        if (session && switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
                if (switch_core_session_compare(session, other_session)) {
@@ -9601,12 +9700,13 @@ switch_status_t sofia_proxy_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua
                                         TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(su_strdup(other_tech_pvt->nh->nh_home, ct))),
                                         TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via)),
                                         TAG_IF(pl, SIPTAG_PAYLOAD_STR(su_strdup(other_tech_pvt->nh->nh_home, pl))),
+                                        TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                         TAG_END());
                }
 
                switch_core_session_rwunlock(other_session);
 
-               nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+               nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
 
                return SWITCH_STATUS_SUCCESS;
        }
@@ -9626,6 +9726,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
        switch_event_t *event;
        private_object_t *tech_pvt = NULL;
        switch_channel_t *channel = NULL;
+       const char *session_id_header = sofia_glue_session_id_header(session, profile);
 
        if (session) {
                tech_pvt = (private_object_t *) switch_core_session_get_private(session);
@@ -9640,21 +9741,28 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
 
                                if (!strcasecmp(sip->sip_content_type->c_subtype, "session-event")) {
                                        if (session) {
+
                                                if (create_info_event(sip, nh, &event) == SWITCH_STATUS_SUCCESS) {
                                                        if (switch_core_session_queue_event(session, &event) == SWITCH_STATUS_SUCCESS) {
                                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "queued freeswitch event for INFO\n");
                                                                nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/session-event-response"),
-                                                                                       SIPTAG_PAYLOAD_STR("+OK MESSAGE QUEUED"), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+                                                                                       SIPTAG_PAYLOAD_STR("+OK MESSAGE QUEUED"), NUTAG_WITH_THIS_MSG(de->data->e_msg),
+                                                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                                       TAG_END());
                                                        } else {
                                                                switch_event_destroy(&event);
                                                                nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/session-event-response"),
-                                                                                       SIPTAG_PAYLOAD_STR("-ERR MESSAGE NOT QUEUED"), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+                                                                                       SIPTAG_PAYLOAD_STR("-ERR MESSAGE NOT QUEUED"), NUTAG_WITH_THIS_MSG(de->data->e_msg),
+                                                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                                       TAG_END());
                                                        }
                                                }
 
                                        } else {
                                                nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/session-event-response"),
-                                                                       SIPTAG_PAYLOAD_STR("-ERR INVALID SESSION"), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+                                                                       SIPTAG_PAYLOAD_STR("-ERR INVALID SESSION"), NUTAG_WITH_THIS_MSG(de->data->e_msg), 
+                                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                       TAG_END());
 
                                        }
 
@@ -9675,10 +9783,15 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
 
                                        if ((status = switch_api_execute(cmd, arg, NULL, &stream)) == SWITCH_STATUS_SUCCESS) {
                                                nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/api-response"),
-                                                                       SIPTAG_PAYLOAD_STR(stream.data), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+                                                                       SIPTAG_PAYLOAD_STR(stream.data), NUTAG_WITH_THIS_MSG(de->data->e_msg), 
+                                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                       TAG_END());
                                        } else {
+
                                                nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/api-response"),
-                                                                       SIPTAG_PAYLOAD_STR("-ERR INVALID COMMAND"), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+                                                                       SIPTAG_PAYLOAD_STR("-ERR INVALID COMMAND"), NUTAG_WITH_THIS_MSG(de->data->e_msg), 
+                                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                                       TAG_END());
                                        }
 
                                        switch_safe_free(stream.data);
@@ -9686,7 +9799,9 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                                        return;
                                }
 
-                               nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+                               nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), 
+                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                               TAG_END());
 
                                return;
                        }
@@ -9724,6 +9839,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                                                TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
                                                TAG_IF(!zstr(unknown), SIPTAG_HEADER_STR(unknown)),
                                                TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via)),
+                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                                TAG_IF(!zstr(pl), SIPTAG_PAYLOAD_STR(pl)),
                                                TAG_END());
                                switch_safe_free(extra_headers);
@@ -9869,7 +9985,9 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                                        }
 
                                        /* Send 200 OK response */
-                                       nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+                                       nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), 
+                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                       TAG_END());
                                } else {
                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
                                                                          "IGNORE INFO DTMF(%c) (This channel was not configured to use INFO DTMF!)\n", dtmf.digit);
@@ -9882,7 +10000,9 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                        if (!zstr(clientcode_header)) {
                                switch_channel_set_variable(channel, "call_clientcode", clientcode_header);
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Setting CMC to %s\n", clientcode_header);
-                               nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+                               nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), 
+                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                               TAG_END());
                        }
                        goto end;
                }
@@ -9890,14 +10010,17 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                if ((rec_header = sofia_glue_get_unknown_header(sip, "record"))) {
                        if (zstr(profile->record_template)) {
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Record attempted but no template defined.\n");
-                               nua_respond(nh, 488, "Recording not enabled", NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+                               nua_respond(nh, 488, "Recording not enabled", NUTAG_WITH_THIS_MSG(de->data->e_msg), 
+                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                               TAG_END());
                        } else {
                                if (!strcasecmp(rec_header, "on")) {
                                        char *file = NULL, *tmp = NULL;
 
                                        if (switch_true(switch_channel_get_variable(channel, "sip_disable_recording"))) {
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Record attempted but is disabled by sip_disable_recording variable.\n");
-                                               nua_respond(nh, 488, "Recording disabled for this channel", NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+                                               nua_respond(nh, 488, "Recording disabled for this channel", NUTAG_WITH_THIS_MSG(de->data->e_msg), 
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                                        } else {
 
                                                tmp = switch_mprintf("%s%s%s", profile->record_path ? profile->record_path : "${recordings_dir}",
@@ -9908,7 +10031,9 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Recording %s to %s\n", switch_channel_get_name(channel),
                                                                file);
                                                switch_safe_free(tmp);
-                                               nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+                                               nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), 
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                               TAG_END());
                                                if (file != profile->record_template) {
                                                        free(file);
                                                        file = NULL;
@@ -9921,9 +10046,13 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Done recording %s to %s\n",
                                                                                  switch_channel_get_name(channel), file);
                                                switch_ivr_stop_record_session(session, file);
-                                               nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+                                               nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), 
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                               TAG_END());
                                        } else {
-                                               nua_respond(nh, 488, "Nothing to stop", NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+                                               nua_respond(nh, 488, "Nothing to stop", NUTAG_WITH_THIS_MSG(de->data->e_msg), 
+                                                               TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                                                               TAG_END());
                                        }
                                }
                        }
@@ -9940,7 +10069,9 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "dispatched freeswitch event for INFO\n");
        }
 
-       nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+       nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), 
+                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
+                       TAG_END());
 
        return;
 
@@ -9975,6 +10106,8 @@ void sofia_handle_sip_i_reinvite(switch_core_session_t *session,
                char via_space[2048];
                char branch[16] = "";
 
+               sofia_glue_store_session_id(session, profile, sip, 0);
+
                sofia_clear_flag(tech_pvt, TFLAG_GOT_ACK);
 
                sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
@@ -10115,6 +10248,10 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
        const char *req_uri = NULL;
        char *req_user = NULL;
        switch_time_t sip_invite_time;
+       const char *session_id_header;
+
+       sofia_glue_store_session_id(session, profile, sip, 0);
+       session_id_header = sofia_glue_session_id_header(session, profile);
 
        if (sip && sip->sip_contact && sip->sip_contact->m_url->url_params) {
                uparams = sip->sip_contact->m_url->url_params;
@@ -10138,7 +10275,8 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
        }
 
        if (!session || (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING))) {
-               nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), TAG_END());
+               nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"),
+                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                goto fail;
        }
 
@@ -10148,13 +10286,15 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
 
        if (!sip || !sip->sip_request || !sip->sip_request->rq_method_name) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received an invalid packet!\n");
-               nua_respond(nh, SIP_503_SERVICE_UNAVAILABLE, TAG_END());
+               nua_respond(nh, SIP_503_SERVICE_UNAVAILABLE,
+                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                goto fail;
        }
 
        if (!(sip->sip_contact)) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO CONTACT!\n");
-               nua_respond(nh, 400, "Missing Contact Header", TAG_END());
+               nua_respond(nh, 400, "Missing Contact Header",
+                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                goto fail;
        }
 
@@ -10372,7 +10512,8 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
                                if (!sofia_test_pflag(profile, PFLAG_AUTH_CALLS)) {
                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl \"%s\"\n", x_auth_ip, switch_str_nil(last_acl));
                                        if (!acl_context) {
-                                               nua_respond(nh, SIP_403_FORBIDDEN, TAG_END());
+                                               nua_respond(nh, SIP_403_FORBIDDEN,
+                                                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                                                goto fail;
                                        } else {
                                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s Rejected by acl \"%s\". Falling back to Digest auth.\n",
@@ -10387,7 +10528,8 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
        if (!is_auth && sofia_test_pflag(profile, PFLAG_AUTH_CALLS) && sofia_test_pflag(profile, PFLAG_AUTH_CALLS_ACL_ONLY)) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP/Port %s %i Rejected by acls and auth-calls-acl-only flag is set, rejecting call\n",
                                                  network_ip, network_port);
-               nua_respond(nh, SIP_403_FORBIDDEN, TAG_END());
+               nua_respond(nh, SIP_403_FORBIDDEN,
+                                       TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
                goto fail;
        }
 
index 46853771b981aaac21fb855de4482ed9ec74a562..b5ac9c51ab51c59c86c5c66b35c0b11ea3a3da33 100644 (file)
@@ -338,6 +338,316 @@ enum tport_tls_verify_policy sofia_glue_str2tls_verify_policy(const char * str){
        return ret;
 }
 
+/* create "local-uuid" */
+int sofia_glue_is_valid_session_uuid(const char *session_uuid)
+{
+       int i;
+       if (zstr(session_uuid) || strlen(session_uuid) != RFC7989_SESSION_UUID_LEN) {
+               return 0;
+       }
+       for (i = 0; i < RFC7989_SESSION_UUID_LEN; i++) {
+               char c = session_uuid[i];
+               if ((c < '0' || c > '9') && (c < 'a' || c > 'f')) {
+                       return 0;
+               }
+       }
+       return 1;
+}
+
+/* NIL session-uuid: 00000000000000000000000000000000 */
+int sofia_glue_is_nil_session_uuid(const char *session_uuid)
+{
+       if (zstr(session_uuid)) {
+               return 0;
+       }
+       if (!memcmp(session_uuid, RFC7989_SESSION_UUID_NULL, RFC7989_SESSION_UUID_LEN)) {
+               return 1;
+       }
+       return 0;
+}
+
+const char *sofia_glue_uuid_to_session_uuid(switch_memory_pool_t *pool, const char *uuid)
+{
+       char *session_uuid = NULL; /*"local-uuid", per rfc7989*/
+       if (zstr(uuid) || strlen(uuid) != 36) return NULL;
+
+       session_uuid = switch_core_alloc(pool, RFC7989_SESSION_UUID_LEN + 1);
+       memcpy(session_uuid, uuid, 8);
+       memcpy(session_uuid + 8, uuid + 9, 4);
+       memcpy(session_uuid + 12, uuid + 14, 4);
+       memcpy(session_uuid + 16, uuid + 19, 4);
+       memcpy(session_uuid + 20, uuid + 24, 12);
+
+       if (!sofia_glue_is_valid_session_uuid(session_uuid)) return NULL;
+
+       return session_uuid;
+}
+
+/* rfc7989 generic params, return 0 if param is disabled from config or invalid. ALL params allowed by default. */
+/* save updated generic params list in chan var. */
+int sofia_glue_check_filter_generic_params(switch_core_session_t *session, sofia_profile_t *profile, char *param)
+{
+
+       char *tmp = NULL;
+       switch_channel_t *channel = switch_core_session_get_channel(session);
+
+       if (zstr(param)) {
+               return 0;
+       }
+       if (profile->rfc7989_filter) {
+               char *found = NULL; char *end = NULL; 
+               char *token_array[100] = { 0 };
+               int tokens = switch_separate_string(profile->rfc7989_filter, ',', token_array, (sizeof(token_array) / sizeof(token_array[0])));
+               tmp = switch_core_session_strdup(session, param);
+               if (tokens) {
+                       int i;
+                       for (i = 0; i < tokens && token_array[i]; i++) {
+                               while ((found = strstr(tmp, token_array[i]))) {
+                                       end = strchr(found, ';');
+                                       if (!end) end = strchr(found, '\0');
+                                       *found = '\0';
+                                       strcat(tmp, found + (end - found));
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, 
+                                               "Session-ID: Dropped generic param: %s\n", token_array[i]); 
+                               }
+                       }
+               }
+       }
+
+       if (tmp) {
+               switch_channel_set_variable(channel, SWITCH_RFC7989_GENERIC_PARAM_VARIABLE, tmp);
+       } else {
+               switch_channel_set_variable(channel, SWITCH_RFC7989_GENERIC_PARAM_VARIABLE, param);
+       }
+
+       return 1;
+}
+/* check and store Session-ID header. */
+/* retrieve "local-uuid" and "remote-uuid" of the remote party. */
+void sofia_glue_store_session_id(switch_core_session_t *session, sofia_profile_t *profile, sip_t const *sip, switch_bool_t is_reply)
+{
+       char *a_id, *b_id, *duped, *p, *remote_param;
+       const char *header = sofia_glue_get_unknown_header(sip, "Session-ID");
+       switch_channel_t *channel = switch_core_session_get_channel(session);
+
+       if (!sofia_test_pflag(profile, PFLAG_RFC7989_SESSION_ID)) return;
+
+       if (!header) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Session-ID: missing header.");
+               return;
+       }
+
+       duped = switch_core_session_strdup(session, header);
+
+       if (zstr(duped)) return;
+
+       a_id = switch_strip_whitespace(duped);
+
+       if (zstr(a_id)) return;
+
+       p = strchr(a_id, ';');
+       if (p) *p = '\0';
+
+       if (!sofia_glue_is_valid_session_uuid(a_id)) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Session-ID: Ignoring \"%s\" parsed as \"%s\"\n", header, a_id);
+               return;
+       }
+
+       /* RFC7329 compatibility */
+       if (is_reply) {
+               const char *temp_id = switch_channel_get_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE);
+               if (!zstr(temp_id) && !memcmp(a_id, temp_id, RFC7989_SESSION_UUID_LEN) ) {
+                       /* 'If a SIP response only contains the "local-uuid" that was sent
+                        *  originally, this comes from a pre-standard implementation and MUST
+                        *  NOT be discarded for removing the nil "remote-uuid". In this
+                        *  case, all future transactions within this dialog MUST contain only
+                        *  the UUID received in the first SIP response" */
+                       switch_channel_set_flag(channel, CF_RFC7329_COMPAT);
+                       switch_channel_set_flag_partner(channel, CF_RFC7329_COMPAT);
+               }
+       }
+
+       /* "local-uuid" field retrieved from remote party will become 
+        * SWITCH_RFC7989_APP_SESSION_ID_VARIABLE in a b2bua role. */
+       if (!zstr(a_id)) {
+               struct private_object *tech_pvt = switch_core_session_get_private(session);
+               switch_channel_set_variable(channel, SWITCH_RFC7989_SESSION_ID_VARIABLE, a_id);
+               if (tech_pvt && tech_pvt->sofia_private && !tech_pvt->sofia_private->rfc7989_uuid) {
+                       tech_pvt->sofia_private->rfc7989_uuid = su_strdup(tech_pvt->nh->nh_home, a_id);
+               }
+       }
+
+       if (!p) {
+               switch_channel_set_flag(channel, CF_RFC7329_COMPAT);
+               switch_channel_set_flag_partner(channel, CF_RFC7329_COMPAT);
+               return;
+       }
+       p++;
+       remote_param = strstr(p, "remote=");
+       if (!remote_param) {
+               switch_channel_set_flag(channel, CF_RFC7329_COMPAT);
+               switch_channel_set_flag_partner(channel, CF_RFC7329_COMPAT);
+               sofia_glue_check_filter_generic_params(session, profile, p);
+               return;
+       } 
+       b_id = remote_param + 7;
+       if (!zstr(b_id) && strlen(b_id) == RFC7989_SESSION_UUID_LEN /*32*/) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session-ID: Set remote-uuid: %s\n", b_id);
+               /*using chan var as placeholder only when UAS or when answer() was called in the dialplan */
+               switch_channel_set_variable(channel, SWITCH_RFC7989_REMOTE_SESSION_ID_VARIABLE, b_id);
+               switch_channel_set_variable_partner(channel, SWITCH_RFC7989_REMOTE_SESSION_ID_VARIABLE, b_id);
+
+       } else {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Session-ID: invalid uuid, ignored.\n");
+       }
+}
+
+/* add "Session-ID:" header */
+char *sofia_glue_session_id_header(switch_core_session_t *session, sofia_profile_t *profile)
+{
+       switch_channel_t *channel;
+       const char *b_id = NULL;
+       const char *a_id = NULL;
+       const char *temp_id = NULL;
+       const char *generic = NULL;
+
+       if (!session) return NULL;
+
+       if (!profile) return NULL;
+
+       if (!sofia_test_pflag(profile, PFLAG_RFC7989_SESSION_ID)) return NULL;
+
+       channel = switch_core_session_get_channel(session);
+
+       a_id = switch_channel_get_variable_partner(channel, SWITCH_RFC7989_SESSION_ID_VARIABLE);
+
+       if (zstr(a_id)) {
+               a_id = switch_channel_get_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE);
+               if (!zstr(a_id) && strlen(a_id) == 36) {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Reformatting app Session-ID: %s\n", a_id);
+                       a_id = sofia_glue_uuid_to_session_uuid(switch_core_session_get_pool(session), a_id);
+                       if (!zstr(a_id)) {
+                               struct private_object *tech_pvt = switch_core_session_get_private(session);
+                               switch_channel_set_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE, a_id);
+                               if (tech_pvt && tech_pvt->sofia_private && !tech_pvt->sofia_private->rfc7989_uuid) {
+                                       tech_pvt->sofia_private->rfc7989_uuid = su_strdup(tech_pvt->nh->nh_home, a_id);
+                               }
+                       }
+               }
+       }
+
+       if (zstr(a_id)) {
+               const char *partner_uuid = switch_channel_get_partner_uuid(channel);
+               if (!zstr(partner_uuid)) {
+                       const char *partner_session_id = sofia_glue_uuid_to_session_uuid(switch_core_session_get_pool(session), partner_uuid);
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Setting \"Session-ID: %s\" from partner leg\n", partner_session_id);
+                       switch_channel_set_variable_partner(channel, SWITCH_RFC7989_SESSION_ID_VARIABLE, partner_session_id);
+                       a_id = partner_session_id;
+               }
+       }
+
+       if (((switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) && zstr(a_id) &&
+                               switch_channel_get_state(channel) == CS_INIT) && switch_channel_test_flag(channel, CF_ORIGINATING)) {
+               /*outbound initial request*/
+               char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
+
+               switch_uuid_str(uuid_str, sizeof(uuid_str));
+               a_id = sofia_glue_uuid_to_session_uuid(switch_core_session_get_pool(session), uuid_str);
+               if (!zstr(a_id)) {
+                       struct private_object *tech_pvt = switch_core_session_get_private(session);
+                       switch_channel_set_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE, a_id);
+                       if (tech_pvt && tech_pvt->sofia_private && !tech_pvt->sofia_private->rfc7989_uuid) {
+                               tech_pvt->sofia_private->rfc7989_uuid = su_strdup(tech_pvt->nh->nh_home, a_id);
+                       }
+               }
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, 
+                               "Session-ID: Outbound initial request. local-uuid: %s", a_id);
+               if (sofia_test_pflag(profile, PFLAG_RFC7989_FORCE_OLD)) {
+                       /*for old (and obsolete) Session-ID RFC7329 */
+                       return switch_core_session_sprintf(session, "Session-ID: %s", a_id);
+               }
+
+               b_id = RFC7989_SESSION_UUID_NULL;
+               return switch_core_session_sprintf(session, "Session-ID: %s;remote=%s", a_id, b_id);
+       }
+
+       temp_id = switch_channel_get_variable(channel, SWITCH_RFC7989_REMOTE_SESSION_ID_VARIABLE);
+       if ((switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) && 
+                       ((switch_channel_get_state(channel) == CS_INIT) || (switch_channel_get_state(channel) == CS_EXECUTE)) &&
+                       zstr(temp_id)) {
+               /* fallback to RFC7329 - "old". */
+               /* inbound initial request, no "remote" param. section 11 of RFC7989. */
+               a_id = switch_channel_get_variable(channel, SWITCH_RFC7989_SESSION_ID_VARIABLE);
+               if (zstr(a_id)) {
+                       a_id = RFC7989_SESSION_UUID_NULL;
+               } else {
+                       switch_channel_set_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE, a_id);
+               }
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Session-ID: Fallback to RFC7329");
+               switch_channel_set_flag(channel, CF_RFC7329_COMPAT);
+               return switch_core_session_sprintf(session, "Session-ID: %s", a_id);
+       }
+       if ((switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) &&
+                       ((switch_channel_get_state(channel) == CS_INIT) || (switch_channel_get_state(channel) == CS_EXECUTE)) && 
+                       sofia_glue_is_nil_session_uuid(temp_id)) {
+               /*inbound initial request*/
+               char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
+
+               switch_uuid_str(uuid_str, sizeof(uuid_str));
+               a_id = sofia_glue_uuid_to_session_uuid(switch_core_session_get_pool(session), uuid_str);
+               if (!zstr(a_id)) {
+                       struct private_object *tech_pvt = switch_core_session_get_private(session);
+                       switch_channel_set_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE, a_id);
+                       if (tech_pvt && tech_pvt->sofia_private) {
+                               tech_pvt->sofia_private->rfc7989_uuid = su_strdup(tech_pvt->nh->nh_home, a_id);
+                       }
+               }
+               b_id = switch_channel_get_variable(channel, SWITCH_RFC7989_SESSION_ID_VARIABLE);
+               if (zstr(b_id)) {
+                       b_id = RFC7989_SESSION_UUID_NULL;
+               }
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, 
+                               "Session-ID: Inbound initial request. local-uuid: %s", a_id);
+               return switch_core_session_sprintf(session, "Session-ID: %s;remote=%s", a_id, b_id);
+       }
+
+       if (zstr(a_id)) {
+               struct private_object *tech_pvt = switch_core_session_get_private(session);
+               /* setting NIL local-uuid should never happen, 
+                * but in case we don't get to set it properly by here, just set it to NIL */
+               if (tech_pvt && tech_pvt->sofia_private && tech_pvt->sofia_private->rfc7989_uuid) {
+                       /* handle BYE after REFER or other cases where the channel is destroyed already and we can't get the chan var */
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session-ID: retrieved local-uuid ");
+                       a_id = tech_pvt->sofia_private->rfc7989_uuid;
+               } else {
+                       a_id = RFC7989_SESSION_UUID_NULL;
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session-ID: NIL local-uuid ");
+               }
+       }
+
+       b_id = switch_channel_get_variable(channel, SWITCH_RFC7989_SESSION_ID_VARIABLE);
+
+       if (zstr(b_id) && switch_channel_test_flag(channel, CF_RFC7329_COMPAT)) {
+               /* fallback to RFC7329 , only one uuid*/
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING ,"Session-ID: Fallback to RFC7329, use one uuid");
+               return switch_core_session_sprintf(session, "Session-ID: %s", a_id);
+       } else if (zstr(b_id)) {
+               b_id = RFC7989_SESSION_UUID_NULL;
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session-ID: set NIL remote-uuid");
+       }
+
+       /* B2B: handle generic params*/
+       generic = switch_channel_get_variable_partner(channel, SWITCH_RFC7989_GENERIC_PARAM_VARIABLE);
+       if (!zstr(generic)) {
+               /* copy generic param (name and val) */
+               return switch_core_session_sprintf(session, "Session-ID: %s;%s", a_id, generic);
+       }
+       if (switch_channel_test_flag(channel, CF_RFC7329_COMPAT)) {
+               return switch_core_session_sprintf(session, "Session-ID: %s", a_id);
+       }
+       return switch_core_session_sprintf(session, "Session-ID: %s;remote=%s", a_id, b_id);
+}
+
 char *sofia_glue_find_parameter_value(switch_core_session_t *session, const char *str, const char *param)
 {
        const char *param_ptr;
@@ -757,6 +1067,8 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
        int require_timer = 1;
        uint8_t is_t38 = 0;
        const char *hold_char = "*";
+       const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
+
 
        if (sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD_INACTIVE) ||
                switch_true(switch_channel_get_variable_dup(tech_pvt->channel, "sofia_hold_inactive", SWITCH_FALSE, -1))) {
@@ -1326,6 +1638,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
                is_t38 = 1;
     }
 
+
        if (sofia_use_soa(tech_pvt)) {
                nua_invite(tech_pvt->nh,
                                   NUTAG_AUTOANSWER(0),
@@ -1336,6 +1649,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
                                   NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
                                   NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
                                   NUTAG_UPDATE_REFRESH(tech_pvt->update_refresher),
+                                  TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                   TAG_IF(sofia_test_flag(tech_pvt, TFLAG_RECOVERED), NUTAG_INVITE_TIMER(UINT_MAX)),
                                   TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
                                   TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),
@@ -1373,6 +1687,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
                                   NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
                                   NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
                                   NUTAG_UPDATE_REFRESH(tech_pvt->update_refresher),
+                                  TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
                                   TAG_IF(sofia_test_flag(tech_pvt, TFLAG_RECOVERED), NUTAG_INVITE_TIMER(UINT_MAX)),
                                   TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
                                   TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),