From fa50712266f0266840771d17c43523451790c74d Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Tue, 18 Mar 2008 20:24:22 +0000 Subject: [PATCH] Tue Mar 18 16:16:49 EDT 2008 Pekka.Pessi@nokia.com * nta: fixed checks for rfc2543 retransmssions/CANCEL/ACK Thanks to Michael Jerris for reporting this problem. fix for SFSIP-49 git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7919 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- libs/sofia-sip/.update | 2 +- libs/sofia-sip/libsofia-sip-ua/nta/nta.c | 10 +- libs/sofia-sip/libsofia-sip-ua/nta/test_nta.c | 124 ++++++++++++++++++ 3 files changed, 130 insertions(+), 6 deletions(-) diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index 85a1937479..307e037ef4 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Wed Mar 5 17:21:10 EST 2008 +Tue Mar 18 16:23:57 EDT 2008 diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c index 903a9760c8..ae52b5660e 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c +++ b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c @@ -5322,9 +5322,9 @@ static nta_incoming_t *incoming_find(nta_agent_t const *agent, !(irq->irq_tag_set && to->a_tag == NULL)) ; /* Match top Via header field */ - else if (str0casecmp(irq->irq_via->v_branch, v->v_branch) == 0 && - strcasecmp(irq->irq_via->v_host, v->v_host) == 0 && - str0cmp(irq->irq_via->v_port, v->v_port) == 0) + else if (str0casecmp(irq->irq_via->v_branch, v->v_branch) != 0 || + strcasecmp(irq->irq_via->v_host, v->v_host) != 0 || + str0cmp(irq->irq_via->v_port, v->v_port) != 0) ; /* Match Request-URI */ else if (url_cmp(irq->irq_rq->rq_url, rq->rq_url)) @@ -5337,9 +5337,9 @@ static nta_incoming_t *incoming_find(nta_agent_t const *agent, return irq; /* found */ if (return_ack && irq->irq_method == sip_method_invite) - *return_ack = irq; + return *return_ack = irq, NULL; else if (return_cancel && irq->irq_method != sip_method_ack) - *return_cancel = irq; + return *return_cancel = irq, NULL; } } diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/test_nta.c b/libs/sofia-sip/libsofia-sip-ua/nta/test_nta.c index 4ee13d7f6d..4b9d4eacd1 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nta/test_nta.c +++ b/libs/sofia-sip/libsofia-sip-ua/nta/test_nta.c @@ -203,6 +203,10 @@ static int test_for_ack_or_timeout(agent_t *ag, nta_incoming_t *irq, sip_t const *sip); +static int wait_for_ack_or_cancel(agent_t *ag, + nta_incoming_t *irq, + sip_t const *sip); + int agent_callback(agent_t *ag, nta_agent_t *nta, msg_t *msg, @@ -321,6 +325,7 @@ int leg_callback_500(agent_t *ag, return 500; } + int new_leg_callback_200(agent_t *ag, nta_leg_t *leg, nta_incoming_t *irq, @@ -363,6 +368,20 @@ int new_leg_callback_200(agent_t *ag, return 200; } +int new_leg_callback_180(agent_t *ag, + nta_leg_t *leg, + nta_incoming_t *irq, + sip_t const *sip) +{ + int status = new_leg_callback_200(ag, leg, irq, sip); + if (status == 200) { + ag->ag_irq = irq; + status = 180; + } + return status; +} + + static client_check_f client_check_to_tag; static client_check_f * const default_checks[] = { @@ -1038,6 +1057,8 @@ int test_tports(agent_t *ag) BEGIN(); + nta_leg_bind(ag->ag_server_leg, leg_callback_200, ag); + *url = *ag->ag_contact->m_url; url->url_port = "*"; url->url_params = "transport=tcp"; @@ -2546,9 +2567,112 @@ int test_merging(agent_t *ag) TEST_P(ag->ag_latest_leg, ag->ag_server_leg); } + while (su_recv(ag->ag_sink_socket, m1, sizeof m1, MSG_TRUNC) >= 0) + ; + + { + /* test INVITE/CANCEL with rfc2543 */ + char const template2[] = + "%s " URL_PRINT_FORMAT " SIP/2.0\r\n" + "Via: SIP/2.0/UDP 127.0.0.1:%s;x-kuik=%p\r\n" + "CSeq: %u %s\r\n" + "Call-ID: %p.dfsdhfsjkhsdjk.dfsjfhsduifhsjfsfjkfsd\r\n" + "From: Evil Forker ;tag=test_nta-%s\r\n" + "To: Bob the Builder %s\r\n" + "Content-Length: 0\r\n" + "\r\n"; + + nta_leg_bind(ag->ag_server_leg, new_leg_callback_180, ag); + + snprintf(m1, sizeof m1, + template2, + "INVITE", URL_PRINT_ARGS(u1), + /* Via */ ag->ag_sink_port, m1, + /* CSeq */ 15, "INVITE", + /* Call-ID */ (void *)(ag + 2), + /* From tag */ "2.6.1", + /* To tag */ ""); + l1 = strlen(m1); + TEST_1((size_t)su_sendto(ag->ag_sink_socket, m1, l1, 0, su, sulen) == l1); + recv_udp(ag, r1, sizeof r1); + + l1 = strlen("SIP/2.0 180 "); + TEST_1(memcmp(r1, "SIP/2.0 180 ", l1) == 0); + + TEST_1(ag->ag_irq); + nta_incoming_bind(ag->ag_irq, wait_for_ack_or_cancel, ag); + + snprintf(m2, sizeof m2, + template2, + "CANCEL", URL_PRINT_ARGS(u1), + /* Via */ ag->ag_sink_port, m1, + /* CSeq */ 15, "CANCEL", + /* Call-ID */ (void *)(ag + 2), + /* From tag */ "2.6.1", + /* To tag */ ""); + l2 = strlen(m2); + + TEST_1((size_t)su_sendto(ag->ag_sink_socket, m2, l2, 0, su, sulen) == l2); + recv_udp(ag, r1, sizeof r1); + recv_udp(ag, r2, sizeof r2); + + l1 = strlen("SIP/2.0 200 "); + TEST_1(strstr(r1, "15 CANCEL")); + TEST_1(memcmp(r1, "SIP/2.0 200 ", l1) == 0); + + TEST_1(strstr(r2, "15 INVITE")); + TEST_1(memcmp(r2, "SIP/2.0 487 ", l1) == 0); + + TEST_1(nta_incoming_status(ag->ag_irq) == 487); + + snprintf(m2, sizeof m2, + template2, + "ACK", URL_PRINT_ARGS(u1), + /* Via */ ag->ag_sink_port, m1, + /* CSeq */ 15, "ACK", + /* Call-ID */ (void *)(ag + 2), + /* From tag */ "2.6.1", + /* To tag */ ""); + l2 = strlen(m2); + + TEST_1((size_t)su_sendto(ag->ag_sink_socket, m2, l2, 0, su, sulen) == l2); + + nta_leg_destroy(ag->ag_bob_leg); ag->ag_bob_leg = NULL; + } + + while (su_recv(ag->ag_sink_socket, m1, sizeof m1, MSG_TRUNC) >= 0) + ; + END(); } +static +int wait_for_ack_or_cancel(agent_t *ag, + nta_incoming_t *irq, + sip_t const *sip) +{ + sip_method_t method; + + method = sip ? sip->sip_request->rq_method : sip_method_unknown; + + if (method == sip_method_cancel) { + nta_incoming_treply(ag->ag_irq, SIP_487_REQUEST_CANCELLED, TAG_END()); + } + else if (method == sip_method_ack) { + nta_incoming_destroy(irq); + ag->ag_irq = NULL; + ag->ag_running = 0; + } + else { /* Timeout */ + nta_incoming_destroy(irq); + ag->ag_irq = NULL; + ag->ag_running = 0; + } + + return 0; +} + + /* ---------------------------------------------------------------------- */ /* Test INVITE, dialogs */