Commit acb819a3 authored by Pekka Pessi's avatar Pekka Pessi

nta.c: always use tport from NTATAG_TPORT() (even if it is bad)

Add tests, too.

darcs-hash:20071122143621-65a35-32aa5c0f426226eb3265d9f759661a8de01adc36.gz
parent 2c803435
......@@ -6336,6 +6336,7 @@ static int outgoing_features(nta_agent_t *agent, nta_outgoing_t *orq,
msg_t *msg, sip_t *sip,
tagi_t *tags);
static void outgoing_prepare_send(nta_outgoing_t *orq);
static void outgoing_send_via(nta_outgoing_t *orq, tport_t *tp);
static void outgoing_send(nta_outgoing_t *orq, int retransmit);
static void outgoing_try_tcp_instead(nta_outgoing_t *orq);
static void outgoing_try_udp_instead(nta_outgoing_t *orq);
......@@ -6877,7 +6878,7 @@ nta_outgoing_t *outgoing_create(nta_agent_t *agent,
int invite_100rel = agent->sa_invite_100rel;
tagi_t const *t;
tport_t const *override_tport = NULL;
tport_t *override_tport = NULL;
if (!agent->sa_tport_ip6)
res_order = nta_res_ip4_only;
......@@ -6981,15 +6982,16 @@ nta_outgoing_t *outgoing_create(nta_agent_t *agent,
tpn = tport_name(override_tport);
orq->orq_user_tport = 1;
}
}
if (route_url) {
if (route_url && !orq->orq_user_tport) {
invalid = nta_tpn_by_url(home, orq->orq_tpn, &scheme, &port, route_url);
if (override_tport) {
scheme = "sip"; /* XXX */
invalid = tport_name_dup(home, orq->orq_tpn, tpn);
if (override_tport) { /* Use transport protocol name from transport */
if (strcmp(orq->orq_tpn->tpn_proto, "*") == 0)
orq->orq_tpn->tpn_proto = tport_name(override_tport)->tpn_proto;
}
resolved = tport_name_is_resolved(orq->orq_tpn);
orq->orq_url = url_hdup(home, sip->sip_request->rq_url);
if (route_url != (url_string_t *)agent->sa_default_proxy)
......@@ -7014,6 +7016,9 @@ nta_outgoing_t *outgoing_create(nta_agent_t *agent,
if (!override_tport)
orq->orq_tpn->tpn_ident = tp_ident;
else
orq->orq_tpn->tpn_ident = tport_name(override_tport)->tpn_ident;
if (comp == NULL)
orq->orq_tpn->tpn_comp = comp;
......@@ -7077,9 +7082,8 @@ nta_outgoing_t *outgoing_create(nta_agent_t *agent,
}
#if HAVE_SOFIA_SRESOLV
if (!override_tport)
if (!resolved)
orq->orq_tpn->tpn_port = port;
if (!resolved)
orq->orq_tpn->tpn_port = port;
orq->orq_resolved = resolved;
#else
orq->orq_resolved = resolved = 1;
......@@ -7099,7 +7103,9 @@ nta_outgoing_t *outgoing_create(nta_agent_t *agent,
agent->sa_stats->as_client_tr++;
orq->orq_hash = NTA_HASH(sip->sip_call_id, sip->sip_cseq->cs_seq);
if (resolved)
if (orq->orq_user_tport)
outgoing_send_via(orq, override_tport);
else if (resolved)
outgoing_prepare_send(orq);
#if HAVE_SOFIA_SRESOLV
else
......@@ -7145,7 +7151,6 @@ outgoing_prepare_send(nta_outgoing_t *orq)
tpn->tpn_port = "";
tp = tport_by_name(sa->sa_tports, tpn);
orq->orq_tport = tport_ref(tp);
if (tpn->tpn_port[0] == '\0') {
if (sips || tport_has_tls(tp))
......@@ -7154,17 +7159,28 @@ outgoing_prepare_send(nta_outgoing_t *orq)
tpn->tpn_port = "5060";
}
if (!orq->orq_tport) {
if (sips) {
SU_DEBUG_3(("nta outgoing create: no secure transport\n"));
outgoing_reply(orq, SIP_416_UNSUPPORTED_URI, 1);
}
else {
SU_DEBUG_3(("nta outgoing create: no transport protocol\n"));
outgoing_reply(orq, 503, "No transport", 1);
}
return;
if (tp) {
outgoing_send_via(orq, tp);
}
else if (sips) {
SU_DEBUG_3(("nta outgoing create: no secure transport\n"));
outgoing_reply(orq, SIP_416_UNSUPPORTED_URI, 1);
}
else {
SU_DEBUG_3(("nta outgoing create: no transport protocol\n"));
outgoing_reply(orq, 503, "No transport", 1);
}
}
/** Send request using given transport */
static void
outgoing_send_via(nta_outgoing_t *orq, tport_t *tp)
{
tport_t *old_tp = orq->orq_tport;
orq->orq_tport = tport_ref(tp);
if (old_tp) tport_unref(old_tp);
if (outgoing_insert_via(orq, agent_tport_via(tp)) < 0) {
SU_DEBUG_3(("nta outgoing create: cannot insert Via line\n"));
......@@ -7197,13 +7213,14 @@ outgoing_prepare_send(nta_outgoing_t *orq)
if (orq->orq_delayed) {
SU_DEBUG_5(("nta: delayed sending %s (%u)\n",
orq->orq_method_name, orq->orq_cseq->cs_seq));
outgoing_queue(sa->sa_out.delayed, orq);
outgoing_queue(orq->orq_agent->sa_out.delayed, orq);
return;
}
outgoing_send(orq, 0);
}
/** Send a request */
static void
outgoing_send(nta_outgoing_t *orq, int retransmit)
......@@ -7225,6 +7242,11 @@ outgoing_send(nta_outgoing_t *orq, int retransmit)
return;
}
if (orq->orq_user_tport && !tport_is_clear_to_send(orq->orq_tport)) {
outgoing_tport_error(agent, orq, NULL, orq->orq_request, EPIPE);
return;
}
if (!retransmit)
orq->orq_sent = now;
......
......@@ -61,6 +61,7 @@ typedef struct client_t client_t;
#include <sofia-sip/su_log.h>
#include <sofia-sip/sofia_features.h>
#include <sofia-sip/hostdomain.h>
#include <sofia-sip/tport.h>
#include <sofia-sip/string0.h>
......@@ -964,6 +965,18 @@ int check_via_with_udp(client_t *ctx, nta_outgoing_t *orq, sip_t const *sip)
return 0;
}
static
int save_and_check_tcp(client_t *ctx, nta_outgoing_t *orq, sip_t const *sip)
{
if (ctx->c_status >= 200 && ctx->c_extra) {
tport_t *tport = nta_outgoing_transport(orq);
TEST_1(tport);
*(tport_t **)ctx->c_extra = tport;
}
return check_via_with_tcp(ctx, orq, sip);
}
static client_check_f * const default_checks[] = {
client_check_to_tag,
......@@ -983,6 +996,7 @@ int test_tports(agent_t *ag)
sip_via_t const *v, *v_udp_only = NULL;
char const *udp_comp = NULL;
char const *tcp_comp = NULL;
tport_t *tcp_tport = NULL;
url_t url[1];
......@@ -1147,11 +1161,13 @@ int test_tports(agent_t *ag)
* of 512 kB
*/
if (tcp) {
client_t ctx[1] = {{ ag, "Test 0.2" }};
client_t ctx[1] = {{ ag, "Test 0.2", save_and_check_tcp, }};
url_t url[1];
sip_payload_t *pl;
usize_t size = 512 * 1024;
ctx->c_extra = &tcp_tport;
*url = *ag->ag_aliases->m_url;
url->url_user = "alice";
url->url_params = "transport=tcp";
......@@ -1173,8 +1189,98 @@ int test_tports(agent_t *ag)
TAG_END());
su_free(ag->ag_home, pl);
TEST_1(!client_run(ctx, 200));
TEST_1(tcp_tport);
TEST_P(ag->ag_latest_leg, ag->ag_server_leg);
}
if (tcp_tport) {
/* Test 0.2.1 - always use transport connection from NTATAG_TPORT()
*
* Test bug reported by geaaru
* - NTATAG_TPORT() is not used if NTATAG_DEFAULT_PROXY() is given
*/
client_t ctx[1] = {{ ag, "Test 0.2.1", save_and_check_tcp }};
url_t url[1];
sip_payload_t *pl;
tport_t *used_tport = NULL;
ctx->c_extra = &used_tport;
TEST(tport_shutdown(tcp_tport, 1), 0); /* Not going to send anymore */
TEST_1(pl = test_payload(ag->ag_home, 512));
ag->ag_expect_leg = ag->ag_server_leg;
ctx->c_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ctx,
NULL,
SIP_METHOD_MESSAGE,
(url_string_t *)url,
SIPTAG_SUBJECT_STR(ctx->c_name),
SIPTAG_FROM(ag->ag_bob),
SIPTAG_TO(ag->ag_alice),
SIPTAG_CONTACT(ag->ag_m_bob),
SIPTAG_PAYLOAD(pl),
NTATAG_DEFAULT_PROXY(ag->ag_obp),
NTATAG_TPORT(tcp_tport),
TAG_END());
su_free(ag->ag_home, pl);
TEST_1(!client_run(ctx, 503));
TEST_P(ag->ag_latest_leg, ag->ag_server_leg);
TEST_1(used_tport == tcp_tport);
tport_unref(tcp_tport), tcp_tport = NULL;
if (v_udp_only) /* Prepare for next test */
TEST_1(tcp_tport = tport_ref(tport_parent(used_tport)));
tport_unref(used_tport);
}
if (tcp_tport) {
/* test 0.2.2 - select transport protocol using NTATAG_TPORT()
*
* Use primary NTATAG_TPORT() to select transport
*/
client_t ctx[1] = {{ ag, "Test 0.2.2", save_and_check_tcp }};
url_t url[1];
sip_payload_t *pl;
tport_t *used_tport = NULL;
ctx->c_extra = &used_tport;
TEST_1(tport_is_primary(tcp_tport));
TEST_1(pl = test_payload(ag->ag_home, 512));
*url = *ag->ag_aliases->m_url;
url->url_user = "alice";
url->url_host = v_udp_only->v_host;
url->url_port = v_udp_only->v_port;
url->url_params = NULL; /* No sigcomp */
ag->ag_expect_leg = ag->ag_server_leg;
ctx->c_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ctx,
(url_string_t *)url,
SIP_METHOD_MESSAGE,
(url_string_t *)url,
SIPTAG_SUBJECT_STR(ctx->c_name),
SIPTAG_FROM(ag->ag_bob),
SIPTAG_TO(ag->ag_alice),
SIPTAG_CONTACT(ag->ag_m_bob),
SIPTAG_PAYLOAD(pl),
NTATAG_TPORT(tcp_tport),
TAG_END());
su_free(ag->ag_home, pl);
TEST_1(!client_run(ctx, 503));
TEST_P(ag->ag_latest_leg, ag->ag_server_leg);
TEST_1(used_tport);
TEST_1(tport_is_tcp(used_tport));
tport_unref(used_tport);
tport_unref(tcp_tport), tcp_tport = NULL;
}
/* Test 0.3
......@@ -1324,7 +1430,8 @@ int test_tports(agent_t *ag)
}
if (udp) {
/* Send a message from default leg to server leg
/* Test 0.6
* Send a message from default leg to server leg
* using a prefilled Via header
*/
client_t ctx[1] = {{ ag, "Test 0.6", check_magic_branch }};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment