[Asterisk-Dev] SIP bug and Polycom phones
Karl Brose
khb at pogo.brose.com
Mon Aug 2 18:17:07 MST 2004
I think this is the correct behavior, since this is after all
a new invite and therefore a new transaction, albeit with prior
associations. It should have a new transaction id (branch).
The association with the prior call leg happens through the Call-ID and
tags, which you're not changing.
In your code you also need to consider the insertion of RFC-3581 rport
parameters.
Therefore,I would like to see more elegant and transparent
implementation of branch creation and header insertion for VIA
I have routines as follows:
static int sip_branch_seq = 0;
static
struct sip_branch
create_branch(void)
{
static struct sip_branch b;
b.time = time((time_t*)0);
b.ip = htonl((unsigned int)bindaddr.sin_addr.s_addr);
b.a = rand();
b.c = rand();
b.serial = sip_branch_seq;
return b;
}
static char *
sprint_branch(struct sip_branch b)
{
static char s[80];
snprintf(s, sizeof(s), "%8.8x%8.8x%8.8x%8.8x%8.8x", b.time,
b.ip, b.a, b.c, b.serial);
return s;
}
enum {
VIA_OLD_BRANCH=0,
VIA_NEW_BRANCH
};
static void
build_via(struct sip_pvt* p, int newbranch)
{
char* rport;
sip_branch_seq++;
if (newbranch==VIA_NEW_BRANCH)
p->branch = create_branch();
if (p->rfc3581)
rport = ";rport";
else
rport = "";
snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP
%s:%d%s;branch=z9hG4bK%s",
OURIPSTRING,
ntohs(externip.sin_port),
rport,
sprint_branch(p->branch)
);
}
With this you can insert
build_via(p, VIA_NEW_BRANCH);
where you have your new code.
Clif Jones wrote:
> I forgot to mention that you must also update the branch ID in a dialog
> for any new
> request with 2 exceptions:
> CANCEL always has the SAME branch ID as the INVITE you are cancelling.
> ACK changes the branch ID from its INVITE only if the INVITE responds with
> a 2XX (success) response code.
> See RFC3261 Section 8.1.1 Via
>
> Christian Hecimovic wrote:
>
>> Hi,
>>
>> Polycom phones track the current SIP transaction with the branch
>> number in the Via header. When Asterisk does a reinvite to set up a
>> native bridge, it does not change the branch number - it's still the
>> magic cookie plus some network info plus an unchanging random number
>> stored in sip_pvt.branch. In short, the branch number stays the same
>> from one invite to the next.
>>
>> To get reinvites to work, I made a very simple fix in
>> transmit_reinvite_with_sdp(). I incremented the branch number and
>> recreated the via field of the sip_pvt struct before making the call
>> to reqprep(). Now Polycom phones perform native bridging; sniffing the
>> network shows that the RTP streams do not touch the server.
>>
>> According to RFC 3261, Section 8.1.1.7, changing the branch number for
>> each new transaction is the correct behaviour. I guess the question
>> is, are reinvites new transactions? Polycom thinks so.
>>
>> Before I submit this little patch, I would really like to hear from
>> anyone who thinks this may destabilise Asterisk with other phones, who
>> assume the branch number will stay the same between invites. I do not
>> have any other phones to test with. The code is as follows:
>>
>> static int transmit_reinvite_with_sdp(struct sip_pvt *p, struct
>> ast_rtp *rtp, struct ast_rtp *vrtp)
>> {
>> struct sip_request req;
>> if (p->canreinvite == REINVITE_UPDATE)
>> reqprep(&req, p, "UPDATE", 0);
>> else {
>> // BEGIN POLYCOM SPECIFIC CODE
>> p->branch++;
>> snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP
>> %s:%d;branch=z9hG4bK%08x", inet_ntoa(p->ourip), ourport, p->branch);
>> // END POLYCOM SPECIFIC CODE
>> reqprep(&req, p, "INVITE", 0);
>> }
>>
>> ... the rest of the function follows.
>>
>> Thanks,
>>
>> Christian
>>
>> _______________________________________________
>> Asterisk-Dev mailing list
>> Asterisk-Dev at lists.digium.com
>> http://lists.digium.com/mailman/listinfo/asterisk-dev
>>
>>
>>
>
More information about the asterisk-dev
mailing list