Commit a215f752 authored by Pekka Pessi's avatar Pekka Pessi

UNDO: nta: added option for processing orphan responses matching with a dialog

The orphan responses matching with the dialog can now be processed by the
response callback.The dialog leg can be created with
NTATAG_RESPONSE_CALLBACK() or a response callback can be later bound to the
leg with nta_leg_bind_response().

This is practically useful only with 200 OK responses to the INVITE that are
retransmitted by the UAS. By default, the retransmission are catched by the
ACK transaction (which then retransmits the ACK request message). However,
after ACK transaction times out, the retransmitted 200 OK indicates most
probably that the ACK request messages do not reach UAS.

Partially fixes the sf.net bug #1750691 reported by Mikhail Zabaluev.

darcs-hash:20070824134120-65a35-b75a200339bb5dfd3057b4528334098e69935e5b.gz
parent 9676a147
......@@ -2671,21 +2671,7 @@ void agent_recv_response(nta_agent_t *agent,
outgoing_default_recv(orq, status, msg, sip);
return;
}
/* Try to match response with a dialog */
{
nta_leg_t *leg = leg_find(agent, NULL, NULL,
sip->sip_call_id,
sip->sip_to->a_tag, sip->sip_to->a_url,
sip->sip_from->a_tag, sip->sip_from->a_url);
if (leg && leg->leg_response_callback) {
int result = leg->leg_response_callback(leg->leg_magic, leg, msg, sip);
if (result != -1)
return;
}
}
if (agent->sa_callback) {
else if (agent->sa_callback) {
SU_DEBUG_5(("nta: %03d %s %s\n", status, phrase, "to message callback"));
/*
* Store message and transport to hook for the duration of the callback
......@@ -2701,9 +2687,9 @@ void agent_recv_response(nta_agent_t *agent,
/* Exactly one Via header, belonging to us */
&& sip->sip_via && !sip->sip_via->v_next
&& agent_has_via(agent, sip->sip_via)) {
agent->sa_stats->as_trless_200++; /* Orphan 200 Ok to INVITE. */
agent->sa_stats->as_trless_200++;
if (agent->sa_is_a_uas) {
/* ACK and BYE it */
/* Orphan 200 Ok to INVITE. ACK and BYE it */
SU_DEBUG_5(("nta: %03d %s %s\n", status, phrase, "is ACK&BYE"));
if (nta_msg_ackbye(agent, msg) != -1)
return;
......@@ -3468,7 +3454,6 @@ nta_leg_t *nta_leg_tcreate(nta_agent_t *agent,
char const *method = NULL;
char const *i_str = NULL, *to_str = NULL, *from_str = NULL, *cs_str = NULL;
url_string_t const *url_string = NULL;
nta_leg_response_f *response_callback = NULL;
int no_dialog = 0;
unsigned rseq = 0;
/* RFC 3261 section 12.2.1.1 */
......@@ -3499,7 +3484,6 @@ nta_leg_t *nta_leg_tcreate(nta_agent_t *agent,
NTATAG_REMOTE_CSEQ_REF(rseq),
SIPTAG_CSEQ_REF(cs),
SIPTAG_CSEQ_STR_REF(cs_str),
NTATAG_RESPONSE_CALLBACK_REF(response_callback),
TAG_END());
ta_end(ta);
......@@ -3609,8 +3593,6 @@ nta_leg_t *nta_leg_tcreate(nta_agent_t *agent,
}
leg->leg_hash = leg->leg_id->i_hash;
leg->leg_response_callback = response_callback;
}
else if (url) {
/* This is "default leg" with a destination URL. */
......@@ -3779,30 +3761,6 @@ void nta_leg_bind(nta_leg_t *leg,
}
}
/**Bind a response callback function to a leg object.
*
* Store the response callback function to a leg object. The response
* callback is used to process incoming responses that do not match an
* ongoing client transaction but match the dialog. The 2XX responses to the
* INVITE can be processed here. If the ACK transaction has timed out, such
* a response is received most probably because the ACK is lost in transit
* and the SIP session should be terminated.
*
* @param leg leg object
* @param callback new callback function (or NULL if no callback is desired)
*
* @sa NTATAG_RESPONSE_CALLBACK()
*
* @NEW_1_12_7
*/
void nta_leg_bind_response(nta_leg_t *leg, nta_leg_response_f *callback)
{
if (leg) {
leg->leg_response_callback = callback;
}
}
/** Add a local tag to the leg.
*
* @param leg leg to be tagged
......
......@@ -361,8 +361,6 @@ struct nta_leg_s
nta_request_f *leg_callback;
nta_leg_magic_t *leg_magic;
nta_agent_t *leg_agent;
nta_leg_response_f *leg_response_callback;
/** Leg URL.
*
* This is the URL used to match incoming requests.
......
......@@ -60,7 +60,6 @@ tag_typedef_t ntatag_target = SIPHDRTAG_NAMED_TYPEDEF(target, contact);
tag_typedef_t ntatag_aliases = SIPHDRTAG_NAMED_TYPEDEF(aliases, contact);
tag_typedef_t ntatag_method = STRTAG_TYPEDEF(method);
tag_typedef_t ntatag_response_callback = PTRTAG_TYPEDEF(response_callback);
tag_typedef_t ntatag_branch_key = STRTAG_TYPEDEF(branch_key);
tag_typedef_t ntatag_ack_branch = STRTAG_TYPEDEF(ack_branch);
tag_typedef_t ntatag_comp = CSTRTAG_TYPEDEF(comp);
......
......@@ -180,11 +180,6 @@ typedef int nta_request_f(nta_leg_magic_t *lmagic,
nta_incoming_t *irq,
sip_t const *sip);
typedef int nta_leg_response_f(nta_leg_magic_t *lmagic,
nta_leg_t *leg,
msg_t *msg,
sip_t *sip);
SOFIAPUBFUN
nta_leg_t *nta_leg_tcreate(nta_agent_t *agent,
nta_request_f *req_callback,
......@@ -251,10 +246,6 @@ SOFIAPUBFUN sip_replaces_t *nta_leg_make_replaces(nta_leg_t *leg,
SOFIAPUBFUN
nta_leg_t *nta_leg_by_replaces(nta_agent_t *, sip_replaces_t const *);
/** Bind response callback to leg */
SOFIAPUBFUN void nta_leg_bind_response(nta_leg_t *leg,
nta_leg_response_f *callback);
/* ----------------------------------------------------------------------
* 6) Prototypes for incoming transactions
*/
......
......@@ -1106,32 +1106,6 @@ NTA_DLL extern tag_typedef_t ntatag_method;
NTA_DLL extern tag_typedef_t ntatag_method_ref;
#define NTATAG_METHOD_REF(x) ntatag_method_ref, tag_str_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_response_callback;
/**Provide response callback to a dialog leg.
*
* The response callback is invoked when a response is received that does
* not match an existing client transaction but which does match the dialog.
*
* @par Used with
* nta_leg_tcreate() \n
*
* @par Parameter type
* pointer to #nta_leg_response_f.
*
* @par Values
* Pointer to a function processing orphan responses or NULL.
*
* @sa nta_leg_bind_response(), nta_msg_ackbye()
*
* @NEW_1_12_7
*/
#define NTATAG_RESPONSE_CALLBACK(x) ntatag_response_callback, tag_cptr_v((x))
NTA_DLL extern tag_typedef_t ntatag_response_callback_ref;
#define NTATAG_RESPONSE_CALLBACK_REF(x) \
ntatag_response_callback_ref, tag_cptr_vr(&(x), (x))
NTA_DLL extern tag_typedef_t ntatag_cancel_487;
/** When a CANCEL is received, automatically return 487 response to original request.
*
......
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