fix issue where rtp stack was not paying attn to header extensions

This commit is contained in:
Anthony Minessale 2012-12-13 19:49:02 -06:00
parent ab886cad30
commit d301451782
3 changed files with 47 additions and 15 deletions

View 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"

View 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

View 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) {
@ -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->last_seq && rtp_session->last_seq+1 != 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) {
//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;