Skip to content

Commit eb5b10a

Browse files
authored
Merge pull request #1428 from meetecho/fix-rtcp-report
Fix SSRCs and RTP timestamps in incoming RTCP reports
2 parents 3af6c6b + 86c1d69 commit eb5b10a

File tree

3 files changed

+99
-4
lines changed

3 files changed

+99
-4
lines changed

ice.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2596,11 +2596,12 @@ static void janus_ice_cb_nice_recv(NiceAgent *agent, guint stream_id, guint comp
25962596
video = 0;
25972597
} else if(rtcp_ssrc == stream->video_ssrc) {
25982598
video = 1;
2599-
} else {
2599+
} else if(janus_rtcp_has_fir(buf, len) || janus_rtcp_has_pli(buf, len) || janus_rtcp_get_remb(buf, len)) {
26002600
/* Mh, no SR or RR? Try checking if there's any FIR, PLI or REMB */
2601-
if(janus_rtcp_has_fir(buf, len) || janus_rtcp_has_pli(buf, len) || janus_rtcp_get_remb(buf, len)) {
2602-
video = 1;
2603-
}
2601+
video = 1;
2602+
} else {
2603+
JANUS_LOG(LOG_WARN,"[%"SCNu64"] Dropping RTCP packet with unknown SSRC (%"SCNu32")\n", handle->handle_id, rtcp_ssrc);
2604+
return;
26042605
}
26052606
JANUS_LOG(LOG_HUGE, "[%"SCNu64"] Incoming RTCP, bundling: this is %s (local SSRC: video=%"SCNu32", audio=%"SCNu32", got %"SCNu32")\n",
26062607
handle->handle_id, video ? "video" : "audio", stream->video_ssrc, stream->audio_ssrc, rtcp_ssrc);
@@ -2618,6 +2619,9 @@ static void janus_ice_cb_nice_recv(NiceAgent *agent, guint stream_id, guint comp
26182619
} else if(stream->video_ssrc_peer[2] && rtcp_ssrc == stream->video_ssrc_peer[2]) {
26192620
video = 1;
26202621
vindex = 2;
2622+
} else {
2623+
JANUS_LOG(LOG_WARN,"[%"SCNu64"] Dropping RTCP packet with unknown SSRC (%"SCNu32")\n", handle->handle_id, rtcp_ssrc);
2624+
return;
26212625
}
26222626
JANUS_LOG(LOG_HUGE, "[%"SCNu64"] Incoming RTCP, bundling: this is %s (remote SSRC: video=%"SCNu32" #%d, audio=%"SCNu32", got %"SCNu32")\n",
26232627
handle->handle_id, video ? "video" : "audio", stream->video_ssrc_peer[vindex], vindex, stream->audio_ssrc_peer, rtcp_ssrc);
@@ -2715,6 +2719,18 @@ static void janus_ice_cb_nice_recv(NiceAgent *agent, guint stream_id, guint comp
27152719
component->retransmit_log_ts = now;
27162720
}
27172721

2722+
/* Fix packet data for RTCP SR and RTCP RR */
2723+
janus_rtp_switching_context *rtp_ctx = video ? &stream->rtp_ctx[vindex] : &stream->rtp_ctx[0];
2724+
uint32_t ssrc_peer = video ? stream->video_ssrc_peer_orig[vindex] : stream->audio_ssrc_peer_orig;
2725+
uint32_t ssrc_local = video ? stream->video_ssrc : stream->audio_ssrc;
2726+
uint32_t ssrc_expected = video ? rtp_ctx->v_last_ssrc : rtp_ctx->a_last_ssrc;
2727+
if (janus_rtcp_fix_report_data(buf, buflen, rtp_ctx, ssrc_peer, ssrc_local, ssrc_expected, video) < 0) {
2728+
/* Drop packet in case of parsing error or SSRC different from the one expected. */
2729+
/* This might happen at the very beginning of the communication or early after */
2730+
/* a re-negotation has been concluded. */
2731+
return;
2732+
}
2733+
27182734
janus_plugin *plugin = (janus_plugin *)handle->app;
27192735
if(plugin && plugin->incoming_rtcp && handle->app_handle &&
27202736
!g_atomic_int_get(&handle->app_handle->stopped) &&

rtcp.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,74 @@ gboolean janus_rtcp_parse_lost_info(char *packet, int len, uint32_t *lost, int *
692692
return FALSE;
693693
}
694694

695+
int janus_rtcp_fix_report_data(char *packet, int len, janus_rtp_switching_context *rtp_ctx, uint32_t ssrc_peer, uint32_t ssrc_local, uint32_t ssrc_expected, gboolean video) {
696+
if(packet == NULL || len <= 0)
697+
return -1;
698+
/* Parse RTCP compound packet */
699+
janus_rtcp_header *rtcp = (janus_rtcp_header *)packet;
700+
if(rtcp->version != 2)
701+
return -2;
702+
int pno = 0, total = len, status = 0;
703+
while(rtcp) {
704+
pno++;
705+
switch(rtcp->type) {
706+
case RTCP_RR: {
707+
janus_rtcp_rr *rr = (janus_rtcp_rr *)rtcp;
708+
uint32_t recv_ssrc = ntohl(rr->ssrc);
709+
if (recv_ssrc != ssrc_expected) {
710+
JANUS_LOG(LOG_WARN,"Incoming RTCP RR SSRC (%"SCNu32") does not match the expected one (%"SCNu32") video=%d\n", recv_ssrc, ssrc_expected, video);
711+
return -3;
712+
}
713+
rr->ssrc = htonl(ssrc_peer);
714+
status++;
715+
if (rr->header.rc > 0) {
716+
rr->rb[0].ssrc = htonl(ssrc_local);
717+
status++;
718+
/* FIXME we need to fix the extended highest sequence number received */
719+
/* FIXME we need to fix the cumulative number of packets lost */
720+
break;
721+
}
722+
break;
723+
}
724+
case RTCP_SR: {
725+
janus_rtcp_sr *sr = (janus_rtcp_sr *)rtcp;
726+
uint32_t recv_ssrc = ntohl(sr->ssrc);
727+
if (recv_ssrc != ssrc_expected) {
728+
JANUS_LOG(LOG_WARN,"Incoming RTCP SR SSRC (%"SCNu32") does not match the expected one (%"SCNu32") video=%d\n", recv_ssrc, ssrc_expected, video);
729+
return -3;
730+
}
731+
sr->ssrc = htonl(ssrc_peer);
732+
/* FIXME we need to fix the sender's packet count */
733+
/* FIXME we need to fix the sender's octet count */
734+
uint32_t sr_ts = ntohl(sr->si.rtp_ts);
735+
uint32_t fix_ts = video ? (sr_ts - rtp_ctx->v_base_ts) + rtp_ctx->v_base_ts_prev :
736+
(sr_ts - rtp_ctx->a_base_ts) + rtp_ctx->a_base_ts_prev;
737+
sr->si.rtp_ts = htonl(fix_ts);
738+
status++;
739+
if (sr->header.rc > 0) {
740+
sr->rb[0].ssrc = htonl(ssrc_local);
741+
status++;
742+
/* FIXME we need to fix the extended highest sequence number received */
743+
/* FIXME we need to fix the cumulative number of packets lost */
744+
break;
745+
}
746+
break;
747+
}
748+
default:
749+
break;
750+
}
751+
/* Is this a compound packet? */
752+
int length = ntohs(rtcp->length);
753+
if(length == 0)
754+
break;
755+
total -= length*4+4;
756+
if(total <= 0)
757+
break;
758+
rtcp = (janus_rtcp_header *)((uint32_t*)rtcp + length + 1);
759+
}
760+
return status;
761+
}
762+
695763
gboolean janus_rtcp_has_bye(char *packet, int len) {
696764
/* Parse RTCP compound packet */
697765
janus_rtcp_header *rtcp = (janus_rtcp_header *)packet;

rtcp.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,17 @@ guint32 janus_rtcp_get_receiver_ssrc(char *packet, int len);
338338
* @returns 0 in case of success, -1 on errors */
339339
int janus_rtcp_parse(janus_rtcp_context *ctx, char *packet, int len);
340340

341+
/*! \brief Method to fix incoming RTCP SR and RR data
342+
* @param[in] packet The message data
343+
* @param[in] len The message data length in bytes
344+
* @param[in] rtp_ctx RTP context to get timestamp info from
345+
* @param[in] ssrc_peer The remote SSRC in usage for this stream
346+
* @param[in] ssrc_local The local SSRC in usage for this stream
347+
* @param[in] ssrc_expected The expected SSRC for this RTCP packet
348+
* @param[in] video Whether the RTCP packet contains report for video data
349+
* @returns The number of fields updated, negative values on errors */
350+
int janus_rtcp_fix_report_data(char *packet, int len, janus_rtp_switching_context *rtp_ctx, uint32_t ssrc_peer, uint32_t ssrc_local, uint32_t ssrc_expected, gboolean video);
351+
341352
/*! \brief Method to fix an RTCP message (http://tools.ietf.org/html/draft-ietf-straw-b2bua-rtcp-00)
342353
* @param[in] ctx RTCP context to update, if needed (optional)
343354
* @param[in] packet The message data

0 commit comments

Comments
 (0)