The ssrc has been used without respect to proper byte ordering. The
timestap_offset and seq_offset variables has been set even when
patching was not allowed.

This patch introduces a new variable 'ssrc' that takes the value of
the SSRC in proper byte order. The offsets in the state are only
updated if SSRC patching is allowed.

Sponsored-by: On-Waves ehf
---
 openbsc/include/openbsc/mgcp_internal.h |    1 +
 openbsc/src/libmgcp/mgcp_network.c      |   73 ++++++++++++++++++++-----------
 openbsc/src/libmgcp/mgcp_protocol.c     |    3 ++
 3 files changed, 52 insertions(+), 25 deletions(-)

diff --git a/openbsc/include/openbsc/mgcp_internal.h 
b/openbsc/include/openbsc/mgcp_internal.h
index 02e193d..b16bd49 100644
--- a/openbsc/include/openbsc/mgcp_internal.h
+++ b/openbsc/include/openbsc/mgcp_internal.h
@@ -59,6 +59,7 @@ struct mgcp_rtp_state {
        int cycles;
 
        int32_t  timestamp_offset;
+       uint32_t packet_duration;
        uint32_t jitter;
        int32_t transit;
 
diff --git a/openbsc/src/libmgcp/mgcp_network.c 
b/openbsc/src/libmgcp/mgcp_network.c
index ce4e1d3..137ddba 100644
--- a/openbsc/src/libmgcp/mgcp_network.c
+++ b/openbsc/src/libmgcp/mgcp_network.c
@@ -216,7 +216,7 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, 
struct mgcp_rtp_state *sta
        uint32_t arrival_time;
        int32_t transit, d;
        uint16_t seq, udelta;
-       uint32_t timestamp;
+       uint32_t timestamp, ssrc;
        struct rtp_hdr *rtp_hdr;
        int payload = rtp_end->payload_type;
 
@@ -227,31 +227,43 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, 
struct mgcp_rtp_state *sta
        seq = ntohs(rtp_hdr->sequence);
        timestamp = ntohl(rtp_hdr->timestamp);
        arrival_time = get_current_ts();
+       ssrc = ntohl(rtp_hdr->ssrc);
 
        if (!state->initialized) {
                state->in_stream.last_seq = seq - 1;
-               state->in_stream.ssrc = state->orig_ssrc = rtp_hdr->ssrc;
+               state->in_stream.ssrc = state->orig_ssrc = ssrc;
                state->in_stream.last_tsdelta = 0;
                state->base_seq = seq;
                state->initialized = 1;
                state->jitter = 0;
                state->transit = arrival_time - timestamp;
+               state->packet_duration =
+                       rtp_end->rate * rtp_end->frames_per_packet *
+                       rtp_end->frame_duration_num /
+                       rtp_end->frame_duration_den;
                state->out_stream = state->in_stream;
                state->out_stream.last_timestamp = timestamp;
-               state->out_stream.ssrc = rtp_hdr->ssrc - 1; /* SSRC change <=> 
initialisation */
+               state->out_stream.ssrc = ssrc - 1; /* SSRC change <=> 
initialisation */
                LOGP(DMGCP, LOGL_INFO,
                        "Initializing stream on 0x%x SSRC: %u timestamp: %u "
+                       "pkt-duration: %d, from %s:%d in %d\n",
+                       ENDPOINT_NUMBER(endp), state->in_stream.ssrc,
+                       state->seq_offset, state->packet_duration,
+                       inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
+                       endp->conn_mode);
+       } else if (state->in_stream.ssrc != ssrc) {
+               int32_t tsdelta;
+
+               LOGP(DMGCP, LOGL_NOTICE,
+                       "The SSRC changed on 0x%x SSRC: %u  "
                        "from %s:%d in %d\n",
                        ENDPOINT_NUMBER(endp), state->in_stream.ssrc,
-                       state->seq_offset,
                        inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
                        endp->conn_mode);
-       } else if (state->in_stream.ssrc != rtp_hdr->ssrc) {
-               int32_t tsdelta = state->out_stream.last_tsdelta;
+
+               tsdelta = state->out_stream.last_tsdelta;
                if (tsdelta == 0) {
-                       tsdelta = rtp_end->rate * rtp_end->frames_per_packet *
-                               rtp_end->frame_duration_num /
-                               rtp_end->frame_duration_den;
+                       tsdelta = state->packet_duration;
                        LOGP(DMGCP, LOGL_NOTICE,
                             "Computed timestamp delta %d based on "
                             "rate %d, num frames %d, frame duration %d/%d\n",
@@ -259,18 +271,25 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, 
struct mgcp_rtp_state *sta
                             rtp_end->frame_duration_num,
                             rtp_end->frame_duration_den);
                }
-               state->in_stream.ssrc = rtp_hdr->ssrc;
-               state->seq_offset = (state->out_stream.last_seq + 1) - seq;
-               state->timestamp_offset =
-                       (state->out_stream.last_timestamp + tsdelta) - 
timestamp;
-               state->patch = rtp_end->force_constant_ssrc;
-               LOGP(DMGCP, LOGL_NOTICE,
-                       "The SSRC changed on 0x%x SSRC: %u offset: %d tsdelta: 
%d "
-                       "from %s:%d in %d\n",
-                       ENDPOINT_NUMBER(endp), state->in_stream.ssrc,
-                       state->seq_offset, tsdelta,
-                       inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
-                       endp->conn_mode);
+               state->in_stream.ssrc = ssrc;
+               if (rtp_end->force_constant_ssrc) {
+                       state->seq_offset =
+                               (state->out_stream.last_seq + 1) - seq;
+                       state->timestamp_offset =
+                               (state->out_stream.last_timestamp + tsdelta) -
+                               timestamp;
+                       state->patch = 1;
+                       ssrc = state->orig_ssrc;
+
+                       LOGP(DMGCP, LOGL_NOTICE,
+                            "SSRC patching enabled on 0x%x SSRC: %u "
+                            "offset: %d tsdelta: %d "
+                            "from %s:%d in %d\n",
+                            ENDPOINT_NUMBER(endp), state->in_stream.ssrc,
+                            state->seq_offset, tsdelta,
+                            inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
+                            endp->conn_mode);
+               }
 
                state->in_stream.last_tsdelta = 0;
        } else {
@@ -278,6 +297,9 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, 
struct mgcp_rtp_state *sta
                check_rtp_timestamp(endp, &state->in_stream, rtp_end, addr,
                                    seq, timestamp, "input",
                                    &state->in_stream.last_tsdelta);
+
+               if (state->patch)
+                       ssrc = state->orig_ssrc;
        }
 
        /* Save before patching */
@@ -288,14 +310,15 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, 
struct mgcp_rtp_state *sta
        if (state->patch) {
                seq += state->seq_offset;
                rtp_hdr->sequence = htons(seq);
-               rtp_hdr->ssrc = state->orig_ssrc;
+               rtp_hdr->ssrc = htonl(ssrc);
 
                timestamp += state->timestamp_offset;
                rtp_hdr->timestamp = htonl(timestamp);
-       }
+       } else
+               ssrc = ntohl(rtp_hdr->ssrc);
 
        /* Check again, whether the timestamps are still valid */
-       if (state->out_stream.ssrc == rtp_hdr->ssrc)
+       if (state->out_stream.ssrc == ssrc)
                check_rtp_timestamp(endp, &state->out_stream, rtp_end, addr,
                                    seq, timestamp, "output",
                                    &state->out_stream.last_tsdelta);
@@ -332,7 +355,7 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, 
struct mgcp_rtp_state *sta
        /* Save output values */
        state->out_stream.last_seq = seq;
        state->out_stream.last_timestamp = timestamp;
-       state->out_stream.ssrc = rtp_hdr->ssrc;
+       state->out_stream.ssrc = ssrc;
 
        if (payload < 0)
                return;
diff --git a/openbsc/src/libmgcp/mgcp_protocol.c 
b/openbsc/src/libmgcp/mgcp_protocol.c
index 6d31ace..8693396 100644
--- a/openbsc/src/libmgcp/mgcp_protocol.c
+++ b/openbsc/src/libmgcp/mgcp_protocol.c
@@ -834,6 +834,9 @@ static struct msgb *handle_modify_con(struct 
mgcp_parse_data *p)
                }
        }
 
+       mgcp_rtp_end_config(endp, 1, &endp->net_end);
+       mgcp_rtp_end_config(endp, 1, &endp->bts_end);
+
        /* modify */
        LOGP(DMGCP, LOGL_DEBUG, "Modified endpoint on: 0x%x Server: %s:%u\n",
                ENDPOINT_NUMBER(endp), inet_ntoa(endp->net_end.addr), 
ntohs(endp->net_end.rtp_port));
-- 
1.7.9.5


Reply via email to