<p>Joshua Colp has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/15631">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_rtp_asterisk: Force resync on SSRC change.<br><br>When an SSRC change occurs the timestamps are likely<br>to change as well. As a result we need to reset the<br>timestamp mapping done in the calc_rxstamp function<br>so that they map properly from timestamp to real<br>time.<br><br>This previously occurred but due to packet<br>retransmission support the explicit setting<br>of the marker bit was not effective.<br><br>ASTERISK-29352<br><br>Change-Id: I2d4c8f93ea24abc1030196706de2d70facf05a5a<br>---<br>M res/res_rtp_asterisk.c<br>1 file changed, 51 insertions(+), 47 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/31/15631/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c</span><br><span>index 21eff54..3fe45a9 100644</span><br><span>--- a/res/res_rtp_asterisk.c</span><br><span>+++ b/res/res_rtp_asterisk.c</span><br><span>@@ -7203,12 +7203,13 @@</span><br><span> }</span><br><span> </span><br><span> static struct ast_frame *ast_rtp_interpret(struct ast_rtp_instance *instance, struct ast_srtp *srtp,</span><br><span style="color: hsl(0, 100%, 40%);">- const struct ast_sockaddr *remote_address, unsigned char *read_area, int length, int prev_seqno)</span><br><span style="color: hsl(120, 100%, 40%);">+      const struct ast_sockaddr *remote_address, unsigned char *read_area, int length, int prev_seqno,</span><br><span style="color: hsl(120, 100%, 40%);">+      unsigned int bundled)</span><br><span> {</span><br><span>   unsigned int *rtpheader = (unsigned int*)(read_area);</span><br><span>        struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);</span><br><span>   struct ast_rtp_instance *instance1;</span><br><span style="color: hsl(0, 100%, 40%);">-     int res = length, hdrlen = 12, seqno, payloadtype, padding, mark, ext, cc;</span><br><span style="color: hsl(120, 100%, 40%);">+    int res = length, hdrlen = 12, ssrc, seqno, payloadtype, padding, mark, ext, cc;</span><br><span>     unsigned int timestamp;</span><br><span>      RAII_VAR(struct ast_rtp_payload_type *, payload, NULL, ao2_cleanup);</span><br><span>         struct frame_list frames;</span><br><span>@@ -7225,6 +7226,7 @@</span><br><span>    }</span><br><span> </span><br><span>        /* Pull out the various other fields we will need */</span><br><span style="color: hsl(120, 100%, 40%);">+  ssrc = ntohl(rtpheader[2]);</span><br><span>  seqno = ntohl(rtpheader[0]);</span><br><span>         payloadtype = (seqno & 0x7f0000) >> 16;</span><br><span>    padding = seqno & (1 << 29);</span><br><span>@@ -7274,6 +7276,42 @@</span><br><span>              return AST_LIST_FIRST(&frames) ? AST_LIST_FIRST(&frames) : &ast_null_frame;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Only non-bundled instances can change/learn the remote's SSRC implicitly. */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!bundled) {</span><br><span style="color: hsl(120, 100%, 40%);">+               /* Force a marker bit and change SSRC if the SSRC changes */</span><br><span style="color: hsl(120, 100%, 40%);">+          if (rtp->themssrc_valid && rtp->themssrc != ssrc) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     struct ast_frame *f, srcupdate = {</span><br><span style="color: hsl(120, 100%, 40%);">+                            AST_FRAME_CONTROL,</span><br><span style="color: hsl(120, 100%, 40%);">+                            .subclass.integer = AST_CONTROL_SRCCHANGE,</span><br><span style="color: hsl(120, 100%, 40%);">+                    };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (!mark) {</span><br><span style="color: hsl(120, 100%, 40%);">+                          if (ast_debug_rtp_packet_is_allowed) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                        ast_debug(0, "(%p) RTP forcing Marker bit, because SSRC has changed\n", instance);</span><br><span style="color: hsl(120, 100%, 40%);">+                          }</span><br><span style="color: hsl(120, 100%, 40%);">+                             mark = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   f = ast_frisolate(&srcupdate);</span><br><span style="color: hsl(120, 100%, 40%);">+                    AST_LIST_INSERT_TAIL(&frames, f, frame_list);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   rtp->seedrxseqno = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                      rtp->rxcount = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                  rtp->rxoctetcount = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                     rtp->cycles = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                   rtp->lastrxseqno = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                      rtp->last_seqno = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                       rtp->last_end_timestamp = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (rtp->rtcp) {</span><br><span style="color: hsl(120, 100%, 40%);">+                           rtp->rtcp->expected_prior = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                          rtp->rtcp->received_prior = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                  }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           rtp->themssrc = ssrc; /* Record their SSRC to put in future RR */</span><br><span style="color: hsl(120, 100%, 40%);">+          rtp->themssrc_valid = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  rtp->rxcount++;</span><br><span>   rtp->rxoctetcount += (res - hdrlen);</span><br><span>      if (rtp->rxcount == 1) {</span><br><span>@@ -7498,13 +7536,14 @@</span><br><span>        struct ast_srtp *srtp;</span><br><span>       RAII_VAR(struct ast_rtp_instance *, child, NULL, rtp_instance_unlock);</span><br><span>       struct ast_sockaddr addr;</span><br><span style="color: hsl(0, 100%, 40%);">-       int res, hdrlen = 12, version, payloadtype, mark;</span><br><span style="color: hsl(120, 100%, 40%);">+     int res, hdrlen = 12, version, payloadtype;</span><br><span>  unsigned char *read_area = rtp->rawdata + AST_FRIENDLY_OFFSET;</span><br><span>    size_t read_area_size = sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET;</span><br><span>       unsigned int *rtpheader = (unsigned int*)(read_area), seqno, ssrc, timestamp, prev_seqno;</span><br><span>    struct ast_sockaddr remote_address = { {0,} };</span><br><span>       struct frame_list frames;</span><br><span>    struct ast_frame *frame;</span><br><span style="color: hsl(120, 100%, 40%);">+      unsigned int bundled;</span><br><span> </span><br><span>    /* If this is actually RTCP let's hop on over and handle it */</span><br><span>   if (rtcp) {</span><br><span>@@ -7781,7 +7820,6 @@</span><br><span> </span><br><span>      /* Pull out the various other fields we will need */</span><br><span>         payloadtype = (seqno & 0x7f0000) >> 16;</span><br><span style="color: hsl(0, 100%, 40%);">-       mark = seqno & (1 << 23);</span><br><span>  seqno &= 0xffff;</span><br><span>         timestamp = ntohl(rtpheader[1]);</span><br><span> </span><br><span>@@ -7793,48 +7831,14 @@</span><br><span> </span><br><span>   AST_LIST_HEAD_INIT_NOLOCK(&frames);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     /* Only non-bundled instances can change/learn the remote's SSRC implicitly. */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (!child && !AST_VECTOR_SIZE(&rtp->ssrc_mapping)) {</span><br><span style="color: hsl(0, 100%, 40%);">-            /* Force a marker bit and change SSRC if the SSRC changes */</span><br><span style="color: hsl(0, 100%, 40%);">-            if (rtp->themssrc_valid && rtp->themssrc != ssrc) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       struct ast_frame *f, srcupdate = {</span><br><span style="color: hsl(0, 100%, 40%);">-                              AST_FRAME_CONTROL,</span><br><span style="color: hsl(0, 100%, 40%);">-                              .subclass.integer = AST_CONTROL_SRCCHANGE,</span><br><span style="color: hsl(0, 100%, 40%);">-                      };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                      if (!mark) {</span><br><span style="color: hsl(0, 100%, 40%);">-                            if (ast_debug_rtp_packet_is_allowed) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                  ast_debug(0, "(%p) RTP forcing Marker bit, because SSRC has changed\n", instance);</span><br><span style="color: hsl(0, 100%, 40%);">-                            }</span><br><span style="color: hsl(0, 100%, 40%);">-                               mark = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-                       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                       f = ast_frisolate(&srcupdate);</span><br><span style="color: hsl(0, 100%, 40%);">-                      AST_LIST_INSERT_TAIL(&frames, f, frame_list);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                       rtp->seedrxseqno = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                        rtp->rxcount = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                    rtp->rxoctetcount = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                       rtp->cycles = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                     rtp->lastrxseqno = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                        rtp->last_seqno = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                 rtp->last_end_timestamp = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                 if (rtp->rtcp) {</span><br><span style="color: hsl(0, 100%, 40%);">-                             rtp->rtcp->expected_prior = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                            rtp->rtcp->received_prior = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                    }</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               rtp->themssrc = ssrc; /* Record their SSRC to put in future RR */</span><br><span style="color: hsl(0, 100%, 40%);">-            rtp->themssrc_valid = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(120, 100%, 40%);">+     bundled = (child || AST_VECTOR_SIZE(&rtp->ssrc_mapping)) ? 1 : 0;</span><br><span> </span><br><span>         prev_seqno = rtp->lastrxseqno;</span><br><span>    rtp->lastrxseqno = seqno;</span><br><span> </span><br><span>     if (!rtp->recv_buffer) {</span><br><span>          /* If there is no receive buffer then we can pass back the frame directly */</span><br><span style="color: hsl(0, 100%, 40%);">-            frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno);</span><br><span style="color: hsl(120, 100%, 40%);">+             frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno, bundled);</span><br><span>           AST_LIST_INSERT_TAIL(&frames, frame, frame_list);</span><br><span>                return AST_LIST_FIRST(&frames);</span><br><span>  } else if (rtp->expectedrxseqno == -1 || seqno == rtp->expectedrxseqno) {</span><br><span>@@ -7849,7 +7853,7 @@</span><br><span>               * return it directly without duplicating it.</span><br><span>                 */</span><br><span>          if (!ast_data_buffer_count(rtp->recv_buffer)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno);</span><br><span style="color: hsl(120, 100%, 40%);">+                     frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno, bundled);</span><br><span>                   AST_LIST_INSERT_TAIL(&frames, frame, frame_list);</span><br><span>                        return AST_LIST_FIRST(&frames);</span><br><span>          }</span><br><span>@@ -7864,7 +7868,7 @@</span><br><span>             * chance it will be overwritten.</span><br><span>             */</span><br><span>          if (!ast_data_buffer_get(rtp->recv_buffer, rtp->expectedrxseqno)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno);</span><br><span style="color: hsl(120, 100%, 40%);">+                     frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno, bundled);</span><br><span>                   AST_LIST_INSERT_TAIL(&frames, frame, frame_list);</span><br><span>                        return AST_LIST_FIRST(&frames);</span><br><span>          }</span><br><span>@@ -7874,7 +7878,7 @@</span><br><span>             * to the head of the frames list and avoid having to duplicate it but this would result in out</span><br><span>               * of order packet processing by libsrtp which we are trying to avoid.</span><br><span>                */</span><br><span style="color: hsl(0, 100%, 40%);">-             frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno));</span><br><span style="color: hsl(120, 100%, 40%);">+          frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno, bundled));</span><br><span>                if (frame) {</span><br><span>                         AST_LIST_INSERT_TAIL(&frames, frame, frame_list);</span><br><span>                        prev_seqno = seqno;</span><br><span>@@ -7889,7 +7893,7 @@</span><br><span>                          break;</span><br><span>                       }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                   frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, payload->buf, payload->size, prev_seqno));</span><br><span style="color: hsl(120, 100%, 40%);">+                       frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, payload->buf, payload->size, prev_seqno, bundled));</span><br><span>                     ast_free(payload);</span><br><span> </span><br><span>                       if (!frame) {</span><br><span>@@ -7935,7 +7939,7 @@</span><br><span> </span><br><span>                    /* If the packet we received is the one we are expecting at this point then add it in */</span><br><span>                     if (rtp->expectedrxseqno == seqno) {</span><br><span style="color: hsl(0, 100%, 40%);">-                         frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno));</span><br><span style="color: hsl(120, 100%, 40%);">+                          frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno, bundled));</span><br><span>                                if (frame) {</span><br><span>                                         AST_LIST_INSERT_TAIL(&frames, frame, frame_list);</span><br><span>                                        prev_seqno = seqno;</span><br><span>@@ -7960,7 +7964,7 @@</span><br><span> </span><br><span>                      payload = (struct ast_rtp_rtcp_nack_payload *)ast_data_buffer_remove(rtp->recv_buffer, rtp->expectedrxseqno);</span><br><span>                  if (payload) {</span><br><span style="color: hsl(0, 100%, 40%);">-                          frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, payload->buf, payload->size, prev_seqno));</span><br><span style="color: hsl(120, 100%, 40%);">+                               frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, payload->buf, payload->size, prev_seqno, bundled));</span><br><span>                             if (frame) {</span><br><span>                                         AST_LIST_INSERT_TAIL(&frames, frame, frame_list);</span><br><span>                                        prev_seqno = rtp->expectedrxseqno;</span><br><span>@@ -7982,7 +7986,7 @@</span><br><span>                         * to be the last packet processed right now and it is also guaranteed that it will always return</span><br><span>                     * non-NULL.</span><br><span>                          */</span><br><span style="color: hsl(0, 100%, 40%);">-                     frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno);</span><br><span style="color: hsl(120, 100%, 40%);">+                     frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno, bundled);</span><br><span>                   AST_LIST_INSERT_TAIL(&frames, frame, frame_list);</span><br><span>                        rtp->expectedrxseqno = seqno + 1;</span><br><span>                         if (rtp->expectedrxseqno == SEQNO_CYCLE_OVER) {</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/15631">change 15631</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/15631"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 16 </div>
<div style="display:none"> Gerrit-Change-Id: I2d4c8f93ea24abc1030196706de2d70facf05a5a </div>
<div style="display:none"> Gerrit-Change-Number: 15631 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>