]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
fix issue where rtp stack was not paying attn to header extensions
authorAnthony Minessale <anthm@freeswitch.org>
Fri, 14 Dec 2012 01:49:02 +0000 (19:49 -0600)
committerAnthony Minessale <anthm@freeswitch.org>
Fri, 14 Dec 2012 01:49:02 +0000 (19:49 -0600)
src/include/switch_rtp.h
src/include/switch_types.h
src/switch_rtp.c

index 0a4ac93643822e8e0eab95fcd10b85b0d3774639..d2421fac9754cdb71f7aa5080b31276f48c19772 100644 (file)
@@ -42,6 +42,7 @@
 SWITCH_BEGIN_EXTERN_C
 #define SWITCH_RTP_MAX_BUF_LEN 16384
 #define SWITCH_RTCP_MAX_BUF_LEN 16384
+#define SWITCH_RTP_MAX_BUF_LEN_WORDS 4094 /* (max / 4) - 2 */
 #define SWITCH_RTP_MAX_CRYPTO_LEN 64
 #define SWITCH_RTP_KEY_LEN 30
 #define SWITCH_RTP_CRYPTO_KEY_32 "AES_CM_128_HMAC_SHA1_32"
index 56df24a743a63dad254c5f7c82289ecb4a82e181..1fa34bbce2686b6734c541660dfa2b048dfa73bd 100644 (file)
@@ -767,6 +767,11 @@ typedef struct {
        unsigned ssrc:32;                       /* synchronization source */
 } switch_rtp_hdr_t;
 
+typedef struct {
+       unsigned length:16;                     /* length                 */
+       unsigned profile:16;            /* defined by profile     */
+} switch_rtp_hdr_ext_t;
+
 #else /*  BIG_ENDIAN */
 
 typedef struct {
@@ -781,6 +786,11 @@ typedef struct {
        unsigned ssrc:32;                       /* synchronization source */
 } switch_rtp_hdr_t;
 
+typedef struct {
+       unsigned profile:16;            /* defined by profile     */
+       unsigned length:16;                     /* length                 */
+} switch_rtp_hdr_ext_t;
+
 #endif
 
 #ifdef _MSC_VER
index 24690292983c94b3cb7779b43087b151b261c52f..df4c63baa764b71bb9cf99b0ece63349a7b94572 100644 (file)
@@ -97,13 +97,18 @@ static switch_hash_t *alloc_hash = NULL;
 typedef struct {
        srtp_hdr_t header;
        char body[SWITCH_RTP_MAX_BUF_LEN];
+       switch_rtp_hdr_ext_t *ext;
+       char *ebody;
 } rtp_msg_t;
 
+#define RTP_BODY(_s) (char *) (_s->recv_msg.ebody ? _s->recv_msg.ebody : _s->recv_msg.body)
+
 typedef struct {
        switch_rtcp_hdr_t header;
        char body[SWITCH_RTCP_MAX_BUF_LEN];
 } rtcp_msg_t;
 
+
 typedef enum {
        VAD_FIRE_TALK = (1 << 0),
        VAD_FIRE_NOT_TALK = (1 << 1)
@@ -345,7 +350,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_
 
 #ifdef DEBUG_2833
        if (rtp_session->dtmf_data.in_digit_sanity && !(rtp_session->dtmf_data.in_digit_sanity % 100)) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sanity %d\n", rtp_session->dtmf_data.in_digit_sanity);
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sanity %d %ld\n", rtp_session->dtmf_data.in_digit_sanity, bytes);
        }
 #endif
 
@@ -364,7 +369,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_
        if (bytes > rtp_header_len && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) &&
                !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833) && rtp_session->recv_te && rtp_session->recv_msg.header.pt == rtp_session->recv_te) {
                switch_size_t len = bytes - rtp_header_len;
-               unsigned char *packet = (unsigned char *) rtp_session->recv_msg.body;
+               unsigned char *packet = (unsigned char *) RTP_BODY(rtp_session);
                int end;
                uint16_t duration;
                char key;
@@ -372,6 +377,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_
                uint32_t ts;
 
                if (!(packet[0] || packet[1] || packet[2] || packet[3]) && len >= 8) {
+
                        switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session");
                        packet += 4;
                        len -= 4;
@@ -398,7 +404,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_
                        }
                }
 #ifdef DEBUG_2833
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "packet[%d]: %02x %02x %02x %02x\n", (int) len, (unsigned) packet[0], (unsigned) packet[1], (unsigned) packet[2], (unsigned) packet[3]);
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "packet[%d]: %02x %02x %02x %02x\n", (int) len, (unsigned char) packet[0], (unsigned char) packet[1], (unsigned char) packet[2], (unsigned char) packet[3]);
 #endif
 
                if (in_digit_seq > rtp_session->dtmf_data.in_digit_seq) {
@@ -407,7 +413,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_
 #ifdef DEBUG_2833
 
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read: %c %u %u %u %u %d %d %s\n",
-                                  key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq,
+                                                         key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq,
                                   ts, duration, rtp_session->recv_msg.header.m, end, end && !rtp_session->dtmf_data.in_digit_ts ? "ignored" : "");
 #endif
 
@@ -488,7 +494,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_
 
                        } else if (!rtp_session->dtmf_data.in_digit_ts) {
 #ifdef DEBUG_2833
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "start %d\n", ts);
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "start %d [%c]\n", ts, key);
 #endif
                                rtp_session->dtmf_data.in_digit_ts = ts;
                                rtp_session->dtmf_data.last_in_digit_ts = ts;
@@ -2872,14 +2878,28 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
        switch_assert(bytes);
  more:
        *bytes = sizeof(rtp_msg_t);
+
        status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock_input, 0, (void *) &rtp_session->recv_msg, bytes);
        ts = ntohl(rtp_session->recv_msg.header.ts);
+       rtp_session->recv_msg.ebody = NULL;
 
        if (*bytes) {
                uint16_t seq = ntohs((uint16_t) rtp_session->recv_msg.header.seq);
+
+               if (rtp_session->recv_msg.header.x) { /* header extensions */
+                       rtp_session->recv_msg.ext = (switch_rtp_hdr_ext_t *) rtp_session->recv_msg.body;
+
+                       rtp_session->recv_msg.ext->length = ntohs(rtp_session->recv_msg.ext->length);
+                       rtp_session->recv_msg.ext->profile = ntohs(rtp_session->recv_msg.ext->profile);
+
+                       if (rtp_session->recv_msg.ext->length < SWITCH_RTP_MAX_BUF_LEN_WORDS) {
+                               rtp_session->recv_msg.ebody = rtp_session->recv_msg.body + (rtp_session->recv_msg.ext->length * 4) + 4;
+                       }
+               }
                
+
+#ifdef DEBUG_MISSED_SEQ                
                if (rtp_session->last_seq && rtp_session->last_seq+1 != seq) {
-#ifdef DEBUG_MISSED_SEQ
                        //2012-11-28 18:33:11.799070 [ERR] switch_rtp.c:2883 Missed -65536 RTP frames from sequence [65536] to [-1] (missed). Time since last read [20021]
                        switch_size_t flushed_packets_diff = rtp_session->stats.inbound.flush_packet_count - rtp_session->last_flush_packet_count;
                        switch_size_t num_missed = (switch_size_t)seq - (rtp_session->last_seq+1);
@@ -2913,8 +2933,9 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
                                                                          flushed_packets_diff, rtp_session->last_read_time ? switch_micro_time_now()-rtp_session->last_read_time : 0);
                                }
                        }
-#endif
+
                }
+#endif
                rtp_session->last_seq = seq;
        }
 
@@ -3026,7 +3047,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
        
        
        if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_BYTESWAP) && rtp_session->recv_msg.header.pt == rtp_session->rpayload) {
-               switch_swap_linear((int16_t *)rtp_session->recv_msg.body, (int) *bytes - rtp_header_len);
+               switch_swap_linear((int16_t *)RTP_BODY(rtp_session), (int) *bytes - rtp_header_len);
        }
 
        if (rtp_session->jb && !rtp_session->pause_jb && rtp_session->recv_msg.header.version == 2 && *bytes) {
@@ -3042,7 +3063,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
                if (stfu_n_eat(rtp_session->jb, rtp_session->last_read_ts, 
                                           ntohs((uint16_t) rtp_session->recv_msg.header.seq),
                                           rtp_session->recv_msg.header.pt,
-                                          rtp_session->recv_msg.body, *bytes - rtp_header_len, rtp_session->timer.samplecount) == STFU_ITS_TOO_LATE) {
+                                          RTP_BODY(rtp_session), *bytes - rtp_header_len, rtp_session->timer.samplecount) == STFU_ITS_TOO_LATE) {
                        
                        goto more;
                }
@@ -3056,7 +3077,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
 
        if (rtp_session->jb && !rtp_session->pause_jb) {
                if ((jb_frame = stfu_n_read_a_frame(rtp_session->jb))) {
-                       memcpy(rtp_session->recv_msg.body, jb_frame->data, jb_frame->dlen);
+                       memcpy(RTP_BODY(rtp_session), jb_frame->data, jb_frame->dlen);
 
                        if (jb_frame->plc) {
                                (*flags) |= SFF_PLC;
@@ -3679,7 +3700,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
                }
 
                if (bytes && rtp_session->recv_msg.header.version != 2) {
-                       uint8_t *data = (uint8_t *) rtp_session->recv_msg.body;
+                       uint8_t *data = (uint8_t *) RTP_BODY(rtp_session);
 
                        if (rtp_session->recv_msg.header.version == 0) {
                                if (rtp_session->ice.ice_user) {
@@ -3724,7 +3745,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
        timer_check:
 
                if (do_cng) {
-                       uint8_t *data = (uint8_t *) rtp_session->recv_msg.body;
+                       uint8_t *data = (uint8_t *) RTP_BODY(rtp_session);
 
                        do_2833(rtp_session, session);
 
@@ -3915,7 +3936,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_read(switch_rtp_t *rtp_session, void
 
        *datalen = bytes;
 
-       memcpy(data, rtp_session->recv_msg.body, bytes);
+       memcpy(data, RTP_BODY(rtp_session), bytes);
 
        return SWITCH_STATUS_SUCCESS;
 }
@@ -3979,7 +4000,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp
 
        bytes = rtp_common_read(rtp_session, &frame->payload, &frame->flags, io_flags);
 
-       frame->data = rtp_session->recv_msg.body;
+       frame->data = RTP_BODY(rtp_session);
        frame->packet = &rtp_session->recv_msg;
        frame->packetlen = bytes;
        frame->source = __FILE__;
@@ -4067,7 +4088,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read(switch_rtp_t *rtp_sessi
        }
 
        bytes = rtp_common_read(rtp_session, payload_type, flags, io_flags);
-       *data = rtp_session->recv_msg.body;
+       *data = RTP_BODY(rtp_session);
 
        if (bytes < 0) {
                *datalen = 0;