/**@internal * UAC tag and route. * * Update dialog tags and route on the UAC side. * * @param own dialog owner * @param ds dialog state * @param sip SIP message containing response used to update dialog * @param rtag if true, set remote tag within the leg * @param initial if true, @a sip is response to initial transaction */ void nua_dialog_uac_route(nua_owner_t *own, nua_dialog_state_t *ds, sip_t const *sip, int rtag, int initial) { int established = nua_dialog_is_established(ds); int status = sip->sip_status->st_status; if (!established && sip->sip_to->a_tag) ds->ds_remote_tag = su_strdup(own, sip->sip_to->a_tag); if (ds->ds_leg == NULL) return; if (initial && status >= 200) nta_leg_client_reroute(ds->ds_leg, sip->sip_record_route, sip->sip_contact, 1); else nta_leg_client_reroute(ds->ds_leg, sip->sip_record_route, sip->sip_contact, 0); ds->ds_route = ds->ds_route || sip->sip_record_route || sip->sip_contact; if (rtag && !established && sip->sip_to->a_tag) nta_leg_rtag(ds->ds_leg, sip->sip_to->a_tag); }
/**@internal * UAS tag and route. * * Update dialog tags and route on the UAS side. * * @param own dialog owner * @param ds dialog state * @param sip SIP message containing response used to update dialog * @param rtag if true, set remote tag within the leg */ void nua_dialog_uas_route(nua_owner_t *own, nua_dialog_state_t *ds, sip_t const *sip, int rtag) { int established = nua_dialog_is_established(ds); if (!established && sip->sip_from->a_tag) ds->ds_remote_tag = su_strdup(own, sip->sip_from->a_tag); if (ds->ds_leg == NULL) return; nta_leg_server_route(ds->ds_leg, sip->sip_record_route, sip->sip_contact); ds->ds_route = ds->ds_route || sip->sip_record_route || sip->sip_contact; if (rtag && !established && sip->sip_from->a_tag) nta_leg_rtag(ds->ds_leg, sip->sip_from->a_tag); }
END_TEST START_TEST(client_2_3_2) { nta_outgoing_t *orq, *tagged, *prack; struct message *request, *r_prack, *r_ack; sip_t *sip; struct event *response; S2_CASE("client-2.3.2", "INVITE with 100rel", "Forked INVITE transaction with 100rel"); orq = nta_outgoing_tcreate(leg, s2_nta_orq_callback, NULL, NULL, SIP_METHOD_INVITE, (url_string_t *)s2sip->udp.contact->m_url, SIPTAG_SUPPORTED_STR("100rel"), TAG_END()); fail_unless(orq != NULL); request = s2_sip_wait_for_request(SIP_METHOD_INVITE); fail_unless(request != NULL); s2_sip_respond_to(request, dialog, SIP_183_SESSION_PROGRESS, SIPTAG_RSEQ_STR("1"), SIPTAG_REQUIRE_STR("100rel"), TAG_END()); response = s2_nta_wait_for(wait_for_orq, orq, wait_for_status, 183, 0); sip = response->sip; tagged = nta_outgoing_tagged(orq, s2_nta_orq_callback, NULL, sip->sip_to->a_tag, sip->sip_rseq); fail_unless(tagged != NULL); fail_unless(nta_leg_rtag(leg, sip->sip_to->a_tag) != NULL); prack = nta_outgoing_prack(leg, tagged, s2_nta_orq_callback, NULL, NULL, sip, TAG_END()); r_prack = s2_sip_wait_for_request(SIP_METHOD_PRACK); fail_unless(r_prack != NULL); s2_sip_respond_to(r_prack, dialog, SIP_200_OK, TAG_END()); s2_sip_free_message(r_prack); response = s2_nta_wait_for(wait_for_orq, prack, wait_for_status, 200, 0); fail_unless(response != NULL); nta_outgoing_destroy(prack); s2_sip_respond_to(request, NULL, SIP_480_TEMPORARILY_UNAVAILABLE, TAG_END()); s2_nta_free_event(response); response = s2_nta_wait_for(wait_for_orq, orq, wait_for_status, 480, 0); fail_unless(response != NULL); s2_nta_free_event(response), response = NULL; r_ack = s2_sip_wait_for_request(SIP_METHOD_ACK); s2_sip_free_message(r_ack); nta_outgoing_destroy(orq), orq = NULL; s2_sip_free_message(request); /* 408 is eventually received by tagged transaction */ response = s2_nta_wait_for(wait_for_orq, tagged, wait_for_status, 408, 0); fail_unless(response != NULL); nta_outgoing_destroy(tagged); s2_nta_free_event(response); }