]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
main/udptl.c: correctly handle udptl sequence wrap around
authorTorrey Searle <torrey@voxbone.com>
Wed, 17 Jul 2019 12:35:50 +0000 (14:35 +0200)
committerTorrey Searle <tsearle@gmail.com>
Tue, 30 Jul 2019 12:49:22 +0000 (06:49 -0600)
incorrect handling of UDPTL squence number wrap arounds causes
loss of packets every time the wrap around occurs

ASTERISK-28483 #close

Change-Id: I33caeb2bf13c574a1ebb81714b58907091d64234

main/udptl.c

index 99a9c74149d69aebd7195f9ff41db109f6addf26..555ae696feb9a662a3a8d25db31fff5a7dc6b8eb 100644 (file)
@@ -405,6 +405,24 @@ static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, unsigned int len)
        seq_no = (buf[0] << 8) | buf[1];
        ptr += 2;
 
+       /* UDPTL sequence numbers are 16 bit so after 0xFFFF comes
+          0 which breaks all packet recovery logic.  To fix this
+          if we see that next expected packet (rx_seq_no) is close
+          to or beyond the wrap around limit & the received packet
+          is still near zero, then we 'unwrap' the received seqno
+          so it has the value it would have had.  After a 16
+          packet grace period (there shouldn't be  more than
+          that many recovery packets) we wrap the expected
+          sequence number around and things can return back
+          to normal */
+       if (seq_no < 0x000F && s->rx_seq_no > 0xFFF0) {
+               /* received seq_no has wrapped adjust it */
+               seq_no += 0x10000;
+       } else {
+               /* otherwise make sure expected rx_seq_no is properly wrapped */
+               s->rx_seq_no &= 0xFFFF;
+       }
+
        /* Break out the primary packet */
        if ((stat1 = decode_open_type(buf, len, &ptr, &ifp, &ifp_len)) != 0)
                return -1;