Exemple #1
0
/**@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);
}
Exemple #2
0
/**@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);
}