Fix sequence number overflow over 16 bits causing codec change in RTP packets.
authorJonathan Rose <jrose@digium.com>
Thu, 27 Oct 2011 19:48:23 +0000 (19:48 +0000)
committerJonathan Rose <jrose@digium.com>
Thu, 27 Oct 2011 19:48:23 +0000 (19:48 +0000)
Sequence number was handled as an unsigned integer (usually 32 bits I think, more
depending on the architecture) and was put into the rtp packet which is basically
just a bunch of bits using an or operation. Sequence number only has 16 bits
allocated to it in an RTP packet anyway, so it would add to the next field which
just happened to be the codec. This makes sure the sequence number is set to be
a 16 bit integer regardless of architecture (hopefully) and also makes it so the
incrementing of the sequence number does bitwise or at the peak of a 16 bit number
so that the value will be set back to 0 when going beyond 65535 anyway.

(closes issue ASTERISK-18291)
Reported by: Will Schick
Review: https://reviewboard.asterisk.org/r/1542/
........

Merged revisions 342602 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 342603 from http://svn.asterisk.org/svn/asterisk/branches/10

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@342604 65c4cc65-6c06-0410-ace0-fbb531ad65f3

res/res_rtp_multicast.c

index 18256e9..fc22ba3 100644 (file)
@@ -89,7 +89,7 @@ struct multicast_rtp {
        /*! Synchronization source value, used when creating/sending the RTP packet */
        unsigned int ssrc;
        /*! Sequence number, used when creating/sending the RTP packet */
-       unsigned int seqno;
+       uint16_t seqno;
 };
 
 /* Forward Declarations */
@@ -228,10 +228,13 @@ static int multicast_rtp_write(struct ast_rtp_instance *instance, struct ast_fra
 
        /* Construct an RTP header for our packet */
        rtpheader = (unsigned char *)(f->data.ptr - hdrlen);
-       put_unaligned_uint32(rtpheader, htonl((2 << 30) | (codec << 16) | (multicast->seqno++) | (0 << 23)));
+       put_unaligned_uint32(rtpheader, htonl((2 << 30) | (codec << 16) | (multicast->seqno)));
        put_unaligned_uint32(rtpheader + 4, htonl(f->ts * 8));
        put_unaligned_uint32(rtpheader + 8, htonl(multicast->ssrc));
 
+       /* Increment sequence number and wrap to 0 if it overflows 16 bits. */
+       multicast->seqno = 0xFFFF & (multicast->seqno + 1);
+
        /* Finally send it out to the eager phones listening for us */
        ast_rtp_instance_get_remote_address(instance, &remote_address);
        res = ast_sendto(multicast->socket, (void *) rtpheader, f->datalen + hdrlen, 0, &remote_address);