On Oct 26, 2009 at 00:54, Frank Durda IV <frank.durda(a)hypercube-llc.com> wrote:
As you may recall, this is a problem where frequently
(well,
virtually all of the time) when SER passed a BYE or CANCEL
message through, the device receiving such messages from SER
would reject them, because the Via: header line that SER added
to the BYE or CANCEL message didn't match the one that SER
added to the INVITE message sent earlier.
The BYE _must_ not have the same branch parameter in Via as the INVITE!
It must be different:
" The branch parameter value MUST be unique across space and time for
all requests sent by the UA. The exceptions to this rule are CANCEL
and ACK for non-2xx responses."
(rfc 3216)
local CANCELs and negative ACK always have the same branch parameter in
Via as the corresponding INVITE (see build_local()).
E2E CANCELs are built differently in 0.9.x. The branch param is always
the same as the INIVTE if syn_branch is 1. If syn_branch is 0 it should
be the same as long as the CANCEL headers are not different from the
INVITE (and according to the RFC they shouldn't be different).
If you want to use syn_branch=0 and support broken CANCELs, then you
could try upgrading to ser 2.1 or sr 3.0
(see
http://sip-router.org/docbook/sip-router/branch/master/modules/tm/tm.html#r…).
I brought this up a couple of times in the list previously.
Sorry, try serdev or sr-dev for bugs or anything involving code.
As there was not any response on this point at all, I
have
done some digging and have a simplified example and analysis
of what SER appears to be doing wrong.
First, here is an example of the problem occurring. Here
are key header lines from the INVITE and a BYE message of
a sample call:
The called switch rejects the BYE with a 481 because
top-most Via:
in the BYE does not match the one from the INVITE.
Either the switch is broken or there is some other problem, as the BYE
Via _must_ be different from the INVITE Via (BYE - INVITE matching is
dialog matching an involves Callid, From and To tags).
Here are the two VIAs added by SER that do not match:
INVITE Via: SIP/2.0/UDP
66.77.88.99;branch=z9hG4bKe47c.7be033a8ca37f0e8a1c6bfe63b043efe.0
BYE Via: SIP/2.0/UDP
66.77.88.99;branch=z9hG4bKf47c.c79c6922afd022e9b4cdf00110f17fd5.0
A review of how SER constructs the branch=nnnn value reveals where
the differences are coming from:
[...]
Based on what I am seeing, it appears that neither the Cseq: nor the
complete To: or From: header lines should have ever been used in
constructing a branch=nnnn value, because of the adverse affects
on CANCEL and BYE messages.
They should for syn_branch==0, because the branch must be unique for
each transaction. From, To and Callid make sure that the branch is
unique for each dialog/call, while cseq makes sure it will be different
for different transactions belonging to the same dialog.
[...]
#4. Any deviation in the From: and To: header lines
between INVITE
and BYE/CANCEL will yield a different branch=nnnn value, even
though the parameters of the From: and To: header lines may still
be perfectly legal and technically identical. Any deviation
may be the result of a sloppy SIP implementation in the calling
equipment, but isn't valid grounds for not handling the message
correctly. Examples include things like alternate number formats
(as in To: sip:8885551212@66.77.88.99:5060 (seen in INVITE)
versus To: <sip:8885551212@66.77.88.99:5060> (seen in CANCEL
from same calling device), or differences in the amount of
whitespace (including trailing whitespace), which is supposed
to be ignored in SIP messages but the MD5 generator doesn't
appear to know that it should ignore whitespace.
This is a problem for broken CANCELs. A possible workaround is to switch
to from and to tags + uris (uris because of rfc2543), instead of the
full from & to.
Any one or a combination of these items (and possibly others)
will cause the current branch=nnnn generation code in SER
to generate a different branch=nnnn value and a receiving
system who is following RFC 3261 will reject the BYE or
CANCEL message that has passed through SER. This is
non-compliant behavior.
For BYE, you only get into this situation if you are using
Record-Route to force the BYE message to pass through SER so
that it can tear down the call (unforce_rtp_proxy() and
similar actions), but for a CANCEL message, anybody can run into
this problem, if syn_branch=0. So, while this defect in the
branch=nnnn generation doesn't affect everybody, it still
appears to be wrong.
Is there by chance a compliant version of char_msg_val()
exists that doesn't have these issues? That is, it doesn't
use the Cseq: header line, and if it uses the From: or To:
header line at all, it computes using only the called/calling
digits, and not anything else that may appear on those
header lines.
No, there is no other version. However in newer versions the CANCEL is
built differently with will solve the changed CANCEL problem.
I also don't understand why this is being
MD5'ed. The RFC only says that the branch must be unique,
and there are lots of cheaper has algorithms out there.
MD5 for small strings is fast enough and its output is relatively small.
If you have an example of a cheaper algorithm with the same properties,
then we could try it.
Andrei