fix issue where rtp stack was not paying attn to header extensions
This commit is contained in:
parent
ab886cad30
commit
d301451782
|
@ -42,6 +42,7 @@
|
||||||
SWITCH_BEGIN_EXTERN_C
|
SWITCH_BEGIN_EXTERN_C
|
||||||
#define SWITCH_RTP_MAX_BUF_LEN 16384
|
#define SWITCH_RTP_MAX_BUF_LEN 16384
|
||||||
#define SWITCH_RTCP_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_MAX_CRYPTO_LEN 64
|
||||||
#define SWITCH_RTP_KEY_LEN 30
|
#define SWITCH_RTP_KEY_LEN 30
|
||||||
#define SWITCH_RTP_CRYPTO_KEY_32 "AES_CM_128_HMAC_SHA1_32"
|
#define SWITCH_RTP_CRYPTO_KEY_32 "AES_CM_128_HMAC_SHA1_32"
|
||||||
|
|
|
@ -767,6 +767,11 @@ typedef struct {
|
||||||
unsigned ssrc:32; /* synchronization source */
|
unsigned ssrc:32; /* synchronization source */
|
||||||
} switch_rtp_hdr_t;
|
} switch_rtp_hdr_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned length:16; /* length */
|
||||||
|
unsigned profile:16; /* defined by profile */
|
||||||
|
} switch_rtp_hdr_ext_t;
|
||||||
|
|
||||||
#else /* BIG_ENDIAN */
|
#else /* BIG_ENDIAN */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -781,6 +786,11 @@ typedef struct {
|
||||||
unsigned ssrc:32; /* synchronization source */
|
unsigned ssrc:32; /* synchronization source */
|
||||||
} switch_rtp_hdr_t;
|
} switch_rtp_hdr_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned profile:16; /* defined by profile */
|
||||||
|
unsigned length:16; /* length */
|
||||||
|
} switch_rtp_hdr_ext_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
|
@ -97,13 +97,18 @@ static switch_hash_t *alloc_hash = NULL;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
srtp_hdr_t header;
|
srtp_hdr_t header;
|
||||||
char body[SWITCH_RTP_MAX_BUF_LEN];
|
char body[SWITCH_RTP_MAX_BUF_LEN];
|
||||||
|
switch_rtp_hdr_ext_t *ext;
|
||||||
|
char *ebody;
|
||||||
} rtp_msg_t;
|
} rtp_msg_t;
|
||||||
|
|
||||||
|
#define RTP_BODY(_s) (char *) (_s->recv_msg.ebody ? _s->recv_msg.ebody : _s->recv_msg.body)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
switch_rtcp_hdr_t header;
|
switch_rtcp_hdr_t header;
|
||||||
char body[SWITCH_RTCP_MAX_BUF_LEN];
|
char body[SWITCH_RTCP_MAX_BUF_LEN];
|
||||||
} rtcp_msg_t;
|
} rtcp_msg_t;
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
VAD_FIRE_TALK = (1 << 0),
|
VAD_FIRE_TALK = (1 << 0),
|
||||||
VAD_FIRE_NOT_TALK = (1 << 1)
|
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
|
#ifdef DEBUG_2833
|
||||||
if (rtp_session->dtmf_data.in_digit_sanity && !(rtp_session->dtmf_data.in_digit_sanity % 100)) {
|
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
|
#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) &&
|
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_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;
|
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;
|
int end;
|
||||||
uint16_t duration;
|
uint16_t duration;
|
||||||
char key;
|
char key;
|
||||||
|
@ -372,6 +377,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_
|
||||||
uint32_t ts;
|
uint32_t ts;
|
||||||
|
|
||||||
if (!(packet[0] || packet[1] || packet[2] || packet[3]) && len >= 8) {
|
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");
|
switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session");
|
||||||
packet += 4;
|
packet += 4;
|
||||||
len -= 4;
|
len -= 4;
|
||||||
|
@ -398,7 +404,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_2833
|
#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
|
#endif
|
||||||
|
|
||||||
if (in_digit_seq > rtp_session->dtmf_data.in_digit_seq) {
|
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
|
#ifdef DEBUG_2833
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read: %c %u %u %u %u %d %d %s\n",
|
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" : "");
|
ts, duration, rtp_session->recv_msg.header.m, end, end && !rtp_session->dtmf_data.in_digit_ts ? "ignored" : "");
|
||||||
#endif
|
#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) {
|
} else if (!rtp_session->dtmf_data.in_digit_ts) {
|
||||||
#ifdef DEBUG_2833
|
#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
|
#endif
|
||||||
rtp_session->dtmf_data.in_digit_ts = ts;
|
rtp_session->dtmf_data.in_digit_ts = ts;
|
||||||
rtp_session->dtmf_data.last_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);
|
switch_assert(bytes);
|
||||||
more:
|
more:
|
||||||
*bytes = sizeof(rtp_msg_t);
|
*bytes = sizeof(rtp_msg_t);
|
||||||
|
|
||||||
status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock_input, 0, (void *) &rtp_session->recv_msg, bytes);
|
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);
|
ts = ntohl(rtp_session->recv_msg.header.ts);
|
||||||
|
rtp_session->recv_msg.ebody = NULL;
|
||||||
|
|
||||||
if (*bytes) {
|
if (*bytes) {
|
||||||
uint16_t seq = ntohs((uint16_t) rtp_session->recv_msg.header.seq);
|
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) {
|
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]
|
//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 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);
|
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);
|
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;
|
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) {
|
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) {
|
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,
|
if (stfu_n_eat(rtp_session->jb, rtp_session->last_read_ts,
|
||||||
ntohs((uint16_t) rtp_session->recv_msg.header.seq),
|
ntohs((uint16_t) rtp_session->recv_msg.header.seq),
|
||||||
rtp_session->recv_msg.header.pt,
|
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;
|
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 (rtp_session->jb && !rtp_session->pause_jb) {
|
||||||
if ((jb_frame = stfu_n_read_a_frame(rtp_session->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) {
|
if (jb_frame->plc) {
|
||||||
(*flags) |= SFF_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) {
|
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->recv_msg.header.version == 0) {
|
||||||
if (rtp_session->ice.ice_user) {
|
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:
|
timer_check:
|
||||||
|
|
||||||
if (do_cng) {
|
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);
|
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;
|
*datalen = bytes;
|
||||||
|
|
||||||
memcpy(data, rtp_session->recv_msg.body, bytes);
|
memcpy(data, RTP_BODY(rtp_session), bytes);
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
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);
|
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->packet = &rtp_session->recv_msg;
|
||||||
frame->packetlen = bytes;
|
frame->packetlen = bytes;
|
||||||
frame->source = __FILE__;
|
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);
|
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) {
|
if (bytes < 0) {
|
||||||
*datalen = 0;
|
*datalen = 0;
|
||||||
|
|
Loading…
Reference in New Issue