<!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>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* FIXME: this should be sincronized since multiple 200 can
be<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* 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>
&nbsp;struct dlg_cell *dlg;
    <br>
&nbsp;struct dlg_entry *d_entry;
    <br>
&nbsp;int i;
    <br>
    <br>
&nbsp;if (d_table==0)
    <br>
&nbsp;&nbsp; goto not_found;
    <br>
    <br>
&nbsp;for( i=0 ; i&lt;d_table-&gt;size; i++ ) {
    <br>
    <br>
&nbsp;&nbsp; d_entry = &amp;(d_table-&gt;entries[i]);
    <br>
    <br>
&nbsp;&nbsp; dlg_lock( d_table, d_entry);
    <br>
    <br>
&nbsp;&nbsp; for( dlg=d_entry-&gt;first ; dlg ; dlg=dlg-&gt;next ) {
    <br>
&nbsp;&nbsp;&nbsp;&nbsp; if (!memcmp(dlg-&gt;callid.s, callid-&gt;s, dlg-&gt;callid.len)) {
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dlg-&gt;state==DLG_STATE_DELETED) {
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dlg_unlock( d_table, d_entry);
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto not_found;
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dlg-&gt;ref++;
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dlg_unlock( d_table, d_entry);
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DBG("DEBUG:dialog:lookup_dlg_callid: dialog callid='%.*s' found
on entry %u.%u\n",
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; callid-&gt;len, ZSW(callid-&gt;s), dlg-&gt;h_id,
dlg-&gt;h_entry);
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return dlg;
    <br>
&nbsp;&nbsp;&nbsp;&nbsp; }
    <br>
&nbsp;&nbsp; }
    <br>
    <br>
&nbsp;&nbsp; dlg_unlock( d_table, d_entry);
    <br>
&nbsp;}
    <br>
    <br>
not_found:
    <br>
&nbsp;DBG("DEBUG:dialog:lookup_dlg: no dialog callid='%.*s' found\n",
    <br>
&nbsp;&nbsp;&nbsp;&nbsp; callid-&gt;len, ZSW(callid-&gt;s));
    <br>
&nbsp;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>
&nbsp;&nbsp; struct dlg_cell *dlg = 0;
    <br>
&nbsp;&nbsp; str val;
    <br>
&nbsp;&nbsp; str callid;
    <br>
&nbsp;&nbsp; int h_entry;
    <br>
&nbsp;&nbsp; int h_id;
    <br>
    <br>
/* If find rm_param do&nbsp; as&nbsp; previously */
    <br>
if (d_rrb.get_route_param( req, &amp;rr_param, &amp;val) == 0) {
    <br>
&nbsp;&nbsp; DBG("DEBUG:dialog:dlg_onroute: route param is '%.*s' (len=%d)\n",
    <br>
&nbsp;&nbsp;&nbsp;&nbsp; val.len, val.s, val.len);
    <br>
    <br>
&nbsp;&nbsp; if ( parse_dlg_rr_param( val.s, val.s+val.len, &amp;h_entry,
&amp;h_id)&lt;0 )
    <br>
&nbsp;&nbsp;&nbsp;&nbsp; return;
    <br>
    <br>
&nbsp;&nbsp; dlg = lookup_dlg( h_entry, h_id);
    <br>
&nbsp;&nbsp; if (dlg==0) {
    <br>
&nbsp;&nbsp;&nbsp;&nbsp; LOG(L_WARN,"WARNING:dialog:dlg_onroute: unable to find dialog\n");
    <br>
&nbsp;&nbsp;&nbsp;&nbsp; return;
    <br>
&nbsp;&nbsp; }
    <br>
&nbsp;}else if (req-&gt;callid){
    <br>
/* If rm_param not found, look for callid */
    <br>
&nbsp;&nbsp; dlg = lookup_dlg_callid(&amp;req-&gt;callid-&gt;body);
    <br>
&nbsp;&nbsp; if (!dlg){
    <br>
&nbsp;&nbsp;&nbsp;&nbsp; DBG("DEBUG:dialog:dlg_onroute: Callid '%.*s' not found\n",
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; req-&gt;callid-&gt;body.len, req-&gt;callid-&gt;body.s);
    <br>
&nbsp;&nbsp;&nbsp;&nbsp; return;
    <br>
&nbsp;&nbsp; }
    <br>
&nbsp;}
    <br>
    <br>
&nbsp;&nbsp; if (use_tight_match) {
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((!req-&gt;callid &amp;&amp;
parse_headers(req,HDR_CALLID_F,0)&lt;0) ||
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !req-&gt;callid) {
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LOG(L_ERR, "ERROR:dialog:dlg_onroute: bad request or "
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "missing CALLID hdr :-/\n");
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; callid = req-&gt;callid-&gt;body;
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trim(&amp;callid);
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dlg-&gt;callid.len!=callid.len ||
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strncmp(dlg-&gt;callid.s,callid.s,callid.len)!=0) {
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LOG(L_WARN,"WARNING:dialog:dlg_onroute: tight matching
failed\n");
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
    <br>
&nbsp;&nbsp; }
    <br>
    <br>
&nbsp;&nbsp; if (req-&gt;first_line.u.request.method_value==METHOD_BYE) {
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (remove_dlg_timer(&amp;dlg-&gt;tl)!=0) {
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unref_dlg( dlg , 1, 0);
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dlg-&gt;state!=DLG_STATE_CONFIRMED)
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LOG(L_WARN, "WARNING:dialog:dlg_onroute: BYE for "
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "unconfirmed dialog ?!\n");
    <br>
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* dialog terminated (BYE) */
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; run_dlg_callbacks( DLGCB_TERMINATED, dlg, req);
    <br>
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unref_dlg(dlg, 2, 1);
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if_update_stat( dlg_enable_stats, active_dlgs, -1);
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;
    <br>
&nbsp;&nbsp; } else {
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* within dialog request */
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; run_dlg_callbacks( DLGCB_REQ_WITHIN, dlg, req);
    <br>
&nbsp;&nbsp; }
    <br>
    <br>
&nbsp;&nbsp; if (req-&gt;first_line.u.request.method_value!=METHOD_ACK) {
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dlg-&gt;lifetime = get_dlg_timeout(req);
    <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; update_dlg_timer( &amp;dlg-&gt;tl, dlg-&gt;lifetime );
    <br>
&nbsp;&nbsp; }
    <br>
    <br>
&nbsp;&nbsp; unref_dlg( dlg , 1, 0);
    <br>
&nbsp;&nbsp; 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>
&nbsp;&nbsp;&nbsp; if($DLG_status == 0 &amp;&amp; method!="BYE" ){ *** assuming latest
patch accepted
      <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xlog("L_INFO", "broken ua, dropping packet\n");
      <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit();
      <br>
&nbsp; }
      <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">&lt;michel@extricom.com&gt;</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>
&gt; Hi Michael,
        <br>
&gt;
        <br>
&gt; as you give you the same answer as to Andy :) :
        <br>
&gt;
        <br>
&gt; "To be honest I'm not fan of complicating my life just to support
        <br>
&gt; broken stuff :)....doing dialog matching in traditional way
(without
        <br>
&gt; using RR stuff) is very costly and since complete, un-altered RR
        <br>
&gt; mirroring is mandatory by RFC3261, I see no point of doing it
        <br>
&gt; different. "
        <br>
&gt;
        <br>
&gt; I think the best approach is to force the UAC vendors to align to
the
        <br>
&gt; SIP specifications.
        <br>
&gt; regards,
        <br>
&gt; bogdan
        <br>
&gt;
        <br>
&gt;
        <br>
&gt; Michel Bensoussan wrote:
        <br>
&gt;&gt; Hi Bogdan
        <br>
&gt;&gt; I'm agree with you, but we cannot control the UAS devices so
we have
        <br>
&gt;&gt; to handle the case it doesn't correctly mirror the RR header.
Can we
        <br>
&gt;&gt; base the dialog states on From and To headers? or Callid? I
        <br>
&gt;&gt; understand the the rr_param is used for fast dialog matching
(dialog
        <br>
&gt;&gt; README). Checking dialog matching with headers (From, To,
...),
        <br>
&gt;&gt; will consequently slowing the transaction?
        <br>
&gt;&gt;
        <br>
&gt;&gt; Regards,
        <br>
&gt;&gt; Michel.
        <br>
&gt;&gt;
        <br>
&gt;&gt; Bogdan-Andrei Iancu wrote:
        <br>
&gt;&gt;&gt; Hi Michel,
        <br>
&gt;&gt;&gt;
        <br>
&gt;&gt;&gt; looking at the net capture, it seams that the UAS device
        <br>
&gt;&gt;&gt; (User-Agent: WLAN660-S VoIP PHONE) does not correctly
mirror the RR
        <br>
&gt;&gt;&gt; header - it is removing the hdr parameters, mirroring only
the URI,
        <br>
&gt;&gt;&gt; which is bogus.
        <br>
&gt;&gt;&gt;
        <br>
&gt;&gt;&gt; regards,
        <br>
&gt;&gt;&gt; bogdan
        <br>
&gt;
        <br>
&gt;
        <br>
&gt;
        <br>
        <br>
      </blockquote>
      <br>
      <br>
    </blockquote>
    <br>
  </blockquote>
  <br>
  <br>
  <br>
</blockquote>
</body>
</html>