<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Hi Bogdan<br>
In dlg_handlers.c, function dlg_onreply(), when updating the To Tag,
there is the following comment:<br>
/* FIXME: this should be sincronized since multiple 200 can
be<br>
* sent out */<br>
I have release 1.1.1.<br>
Is multiple 200 OK is supported in newer version?<br>
<br>
What do you mean by "upload the patch on the tracker"? How can I do
that?<br>
May be it's better to wait for dialog match based on Callid <b>and</b>
Tags?<br>
<br>
Regards,<br>
Michel.<br>
<br>
<br>
Bogdan-Andrei Iancu wrote:
<blockquote cite="mid45E5BF80.5090204@voice-system.ro" type="cite">Hi
Michel,
<br>
<br>
only callid matching is not enough - you should also check the tags. In
the mean while, please upload the patch on the tracker. As I said in
the previous email, my only concern is about performance, as you will
have to check all requests and not the only marked for dialog tracking.
<br>
<br>
regards,
<br>
bogdan
<br>
<br>
Michel Bensoussan wrote:
<br>
<blockquote type="cite">Hi
<br>
If I understand your solution, you don't allow the session. And what if
($dlg_count != 0) ?
<br>
<br>
I tried this. It seems to work but I just quick check it.
<br>
The key in "Callid" but I'm not sure it is a good choice. Maybe "To" is
better.
<br>
<br>
Add the following function in dlg_hash.c:
<br>
(based on release 1.1.1)
<br>
<br>
struct dlg_cell* lookup_dlg_callid(str* callid)
<br>
{
<br>
struct dlg_cell *dlg;
<br>
struct dlg_entry *d_entry;
<br>
int i;
<br>
<br>
if (d_table==0)
<br>
goto not_found;
<br>
<br>
for( i=0 ; i<d_table->size; i++ ) {
<br>
<br>
d_entry = &(d_table->entries[i]);
<br>
<br>
dlg_lock( d_table, d_entry);
<br>
<br>
for( dlg=d_entry->first ; dlg ; dlg=dlg->next ) {
<br>
if (!memcmp(dlg->callid.s, callid->s, dlg->callid.len)) {
<br>
if (dlg->state==DLG_STATE_DELETED) {
<br>
dlg_unlock( d_table, d_entry);
<br>
goto not_found;
<br>
}
<br>
dlg->ref++;
<br>
dlg_unlock( d_table, d_entry);
<br>
DBG("DEBUG:dialog:lookup_dlg_callid: dialog callid='%.*s' found
on entry %u.%u\n",
<br>
callid->len, ZSW(callid->s), dlg->h_id,
dlg->h_entry);
<br>
return dlg;
<br>
}
<br>
}
<br>
<br>
dlg_unlock( d_table, d_entry);
<br>
}
<br>
<br>
not_found:
<br>
DBG("DEBUG:dialog:lookup_dlg: no dialog callid='%.*s' found\n",
<br>
callid->len, ZSW(callid->s));
<br>
return 0;
<br>
}
<br>
<br>
<br>
In dlg_handlers.c, modify dlg_onroute() as following:
<br>
<br>
void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
<br>
{
<br>
struct dlg_cell *dlg = 0;
<br>
str val;
<br>
str callid;
<br>
int h_entry;
<br>
int h_id;
<br>
<br>
/* If find rm_param do as previously */
<br>
if (d_rrb.get_route_param( req, &rr_param, &val) == 0) {
<br>
DBG("DEBUG:dialog:dlg_onroute: route param is '%.*s' (len=%d)\n",
<br>
val.len, val.s, val.len);
<br>
<br>
if ( parse_dlg_rr_param( val.s, val.s+val.len, &h_entry,
&h_id)<0 )
<br>
return;
<br>
<br>
dlg = lookup_dlg( h_entry, h_id);
<br>
if (dlg==0) {
<br>
LOG(L_WARN,"WARNING:dialog:dlg_onroute: unable to find dialog\n");
<br>
return;
<br>
}
<br>
}else if (req->callid){
<br>
/* If rm_param not found, look for callid */
<br>
dlg = lookup_dlg_callid(&req->callid->body);
<br>
if (!dlg){
<br>
DBG("DEBUG:dialog:dlg_onroute: Callid '%.*s' not found\n",
<br>
req->callid->body.len, req->callid->body.s);
<br>
return;
<br>
}
<br>
}
<br>
<br>
if (use_tight_match) {
<br>
if ((!req->callid &&
parse_headers(req,HDR_CALLID_F,0)<0) ||
<br>
!req->callid) {
<br>
LOG(L_ERR, "ERROR:dialog:dlg_onroute: bad request or "
<br>
"missing CALLID hdr :-/\n");
<br>
return;
<br>
}
<br>
callid = req->callid->body;
<br>
trim(&callid);
<br>
if (dlg->callid.len!=callid.len ||
<br>
strncmp(dlg->callid.s,callid.s,callid.len)!=0) {
<br>
LOG(L_WARN,"WARNING:dialog:dlg_onroute: tight matching
failed\n");
<br>
return;
<br>
}
<br>
}
<br>
<br>
if (req->first_line.u.request.method_value==METHOD_BYE) {
<br>
if (remove_dlg_timer(&dlg->tl)!=0) {
<br>
unref_dlg( dlg , 1, 0);
<br>
return;
<br>
}
<br>
if (dlg->state!=DLG_STATE_CONFIRMED)
<br>
LOG(L_WARN, "WARNING:dialog:dlg_onroute: BYE for "
<br>
"unconfirmed dialog ?!\n");
<br>
<br>
/* dialog terminated (BYE) */
<br>
run_dlg_callbacks( DLGCB_TERMINATED, dlg, req);
<br>
<br>
unref_dlg(dlg, 2, 1);
<br>
if_update_stat( dlg_enable_stats, active_dlgs, -1);
<br>
return;
<br>
} else {
<br>
/* within dialog request */
<br>
run_dlg_callbacks( DLGCB_REQ_WITHIN, dlg, req);
<br>
}
<br>
<br>
if (req->first_line.u.request.method_value!=METHOD_ACK) {
<br>
dlg->lifetime = get_dlg_timeout(req);
<br>
update_dlg_timer( &dlg->tl, dlg->lifetime );
<br>
}
<br>
<br>
unref_dlg( dlg , 1, 0);
<br>
return;
<br>
}
<br>
<br>
<br>
<br>
<br>
Andy Pyles wrote:
<br>
<blockquote type="cite">HI Michel,
<br>
<br>
Well here's what I'm doing:
<br>
<br>
if ( loose_route() {
<br>
if($DLG_status == 0 && method!="BYE" ){ *** assuming latest
patch accepted
<br>
xlog("L_INFO", "broken ua, dropping packet\n");
<br>
exit();
<br>
}
<br>
}
<br>
<br>
This isn't the most elegant solution, but in my case works ok.
<br>
Basically Lets say the UAC is broken. The first opportunity to tell it
<br>
is "broken" is when it sends an ACK to the 200 OK.
<br>
At this point, it would be very nice to have an option to send "BYE",
<br>
but as this functionality isn't there yet, we just reject the ACK, and
<br>
eventually the broken UAC will send a bye.
<br>
<br>
There may be other corner cases as well, but you get the general idea.
<br>
<br>
Andy
<br>
<br>
<br>
On 2/26/07, Michel Bensoussan <a class="moz-txt-link-rfc2396E" href="mailto:michel@extricom.com"><michel@extricom.com></a> wrote:
<br>
<blockquote type="cite">Hi
<br>
<br>
"I think the best approach is to force the UAC vendors to align to the
<br>
SIP specifications."
<br>
<br>
Well..... Good luck.
<br>
I don't know why but I think if I call and tell them "get back all you
<br>
products and upgrade them to align to the SIP specification" they won't
<br>
listen to me. But may be I'm wrong.
<br>
<br>
Any way. I have to deal with it. Do you have some suggestions? What is
<br>
the best dialog module version to start with?
<br>
<br>
I'm not familiar with SIP but I understand that the "To" header won't
<br>
change during a session. Is that right? I'm not sure the "CallID" will
<br>
be them same in case of re-INVITE.
<br>
So I can save the "To" header in the dialog table and check it if the
<br>
rm_param is not found.
<br>
I'm not sure how to do this.
<br>
<br>
Andy, If you have some suggestions too...
<br>
<br>
Regards,
<br>
Michel.
<br>
<br>
Bogdan-Andrei Iancu wrote:
<br>
> Hi Michael,
<br>
>
<br>
> as you give you the same answer as to Andy :) :
<br>
>
<br>
> "To be honest I'm not fan of complicating my life just to support
<br>
> broken stuff :)....doing dialog matching in traditional way
(without
<br>
> using RR stuff) is very costly and since complete, un-altered RR
<br>
> mirroring is mandatory by RFC3261, I see no point of doing it
<br>
> different. "
<br>
>
<br>
> I think the best approach is to force the UAC vendors to align to
the
<br>
> SIP specifications.
<br>
> regards,
<br>
> bogdan
<br>
>
<br>
>
<br>
> Michel Bensoussan wrote:
<br>
>> Hi Bogdan
<br>
>> I'm agree with you, but we cannot control the UAS devices so
we have
<br>
>> to handle the case it doesn't correctly mirror the RR header.
Can we
<br>
>> base the dialog states on From and To headers? or Callid? I
<br>
>> understand the the rr_param is used for fast dialog matching
(dialog
<br>
>> README). Checking dialog matching with headers (From, To,
...),
<br>
>> will consequently slowing the transaction?
<br>
>>
<br>
>> Regards,
<br>
>> Michel.
<br>
>>
<br>
>> Bogdan-Andrei Iancu wrote:
<br>
>>> Hi Michel,
<br>
>>>
<br>
>>> looking at the net capture, it seams that the UAS device
<br>
>>> (User-Agent: WLAN660-S VoIP PHONE) does not correctly
mirror the RR
<br>
>>> header - it is removing the hdr parameters, mirroring only
the URI,
<br>
>>> which is bogus.
<br>
>>>
<br>
>>> regards,
<br>
>>> bogdan
<br>
>
<br>
>
<br>
>
<br>
<br>
</blockquote>
<br>
<br>
</blockquote>
<br>
</blockquote>
<br>
<br>
<br>
</blockquote>
</body>
</html>