From 94e3c8f9cb10798044ea6a4e4d2144ce605156ae Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 28 Sep 2016 13:55:01 -0400 Subject: [PATCH] TT#3881 re-enable selective packet loop check instead of outright rejecting local endpoints advertised by remote clients (to allow for deliberately daisy chaining packet streams), we flag them for checking against actual packet loops as we did before Change-Id: I5652e86e12f3c1c5053ea70b01e8d128ebf47751 --- daemon/call.c | 24 +++++++---------------- daemon/call.h | 2 +- daemon/media_socket.c | 44 ++++++++++++++++++++++--------------------- 3 files changed, 31 insertions(+), 39 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index 12a18c1c6..1ef33a2d3 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -1499,12 +1499,13 @@ static int get_algorithm_num_ports(GQueue *streams, char *algorithm) { static void __endpoint_loop_protect(struct stream_params *sp, struct call_media *media) { struct intf_address intf_addr; - struct packet_stream *ps; /* check if the advertised endpoint is one of our own addresses. this can * happen by mistake, or it's expected when ICE is in use and passthrough - * mode is enabled (in particular when using ICE=force-relay). ignore such - * an endpoint and revert to what we had before. */ + * mode is enabled (in particular when using ICE=force-relay). we still + * accept such an endpoint, but flag it for potential loop, which we will + * check for later. + * */ intf_addr.type = socktype_udp; // if (other_media->protocol && other_media->protocol->tcp) @@ -1513,21 +1514,10 @@ static void __endpoint_loop_protect(struct stream_params *sp, struct call_media if (!is_local_endpoint(&intf_addr, sp->rtp_endpoint.port)) return; - if (media->streams.head) { - ps = media->streams.head->data; - sp->rtp_endpoint = ps->advertised_endpoint; - ps = ps->rtcp_sibling; - if (ps) - sp->rtcp_endpoint = ps->advertised_endpoint; - else - ZERO(sp->rtcp_endpoint); - } - else - ZERO(sp->rtp_endpoint); + ilog(LOG_DEBUG, "Detected local endpoint advertised by remote client, " + "enabling loop checking"); - ilog(LOG_DEBUG, "Detected local endpoint advertised by remote client. " - "Ignoring and reverting to %s", - endpoint_print_buf(&sp->rtp_endpoint)); + MEDIA_SET(media, LOOP_CHECK); } /* called with call->master_lock held in W */ diff --git a/daemon/call.h b/daemon/call.h index 61242c58b..5879f6eab 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -93,7 +93,6 @@ enum call_type { #define RTP_BUFFER_TAIL_ROOM 512 #define RTP_BUFFER_SIZE (MAX_RTP_PACKET_SIZE + RTP_BUFFER_HEAD_ROOM + RTP_BUFFER_TAIL_ROOM) -#define RTP_LOOP_PROTECT 0 // disable #ifndef RTP_LOOP_PROTECT #define RTP_LOOP_PROTECT 28 /* number of bytes */ #define RTP_LOOP_PACKETS 2 /* number of packets */ @@ -172,6 +171,7 @@ enum call_type { #define MEDIA_FLAG_TRICKLE_ICE SHARED_FLAG_TRICKLE_ICE #define MEDIA_FLAG_ICE_LITE SHARED_FLAG_ICE_LITE #define MEDIA_FLAG_ICE_CONTROLLING 0x00200000 +#define MEDIA_FLAG_LOOP_CHECK 0x00400000 /* access macros */ #define SP_ISSET(p, f) bf_isset(&(p)->sp_flags, SP_FLAG_ ## f) diff --git a/daemon/media_socket.c b/daemon/media_socket.c index 676cc9446..d7e972103 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -1126,32 +1126,34 @@ static int stream_packet(struct stream_fd *sfd, str *s, const endpoint_t *fsin, } #if RTP_LOOP_PROTECT - mutex_lock(&stream->in_lock); + if (MEDIA_ISSET(media, LOOP_CHECK)) { + mutex_lock(&stream->in_lock); - for (i = 0; i < RTP_LOOP_PACKETS; i++) { - if (stream->lp_buf[i].len != s->len) - continue; - if (memcmp(stream->lp_buf[i].buf, s->s, MIN(s->len, RTP_LOOP_PROTECT))) - continue; + for (i = 0; i < RTP_LOOP_PACKETS; i++) { + if (stream->lp_buf[i].len != s->len) + continue; + if (memcmp(stream->lp_buf[i].buf, s->s, MIN(s->len, RTP_LOOP_PROTECT))) + continue; - __C_DBG("packet dupe"); - if (stream->lp_count >= RTP_LOOP_MAX_COUNT) { - ilog(LOG_WARNING, "More than %d duplicate packets detected, dropping packet " - "to avoid potential loop", RTP_LOOP_MAX_COUNT); - goto done; - } + __C_DBG("packet dupe"); + if (stream->lp_count >= RTP_LOOP_MAX_COUNT) { + ilog(LOG_WARNING, "More than %d duplicate packets detected, dropping packet " + "to avoid potential loop", RTP_LOOP_MAX_COUNT); + goto done; + } - stream->lp_count++; - goto loop_ok; - } + stream->lp_count++; + goto loop_ok; + } - /* not a dupe */ - stream->lp_count = 0; - stream->lp_buf[stream->lp_idx].len = s->len; - memcpy(stream->lp_buf[stream->lp_idx].buf, s->s, MIN(s->len, RTP_LOOP_PROTECT)); - stream->lp_idx = (stream->lp_idx + 1) % RTP_LOOP_PACKETS; + /* not a dupe */ + stream->lp_count = 0; + stream->lp_buf[stream->lp_idx].len = s->len; + memcpy(stream->lp_buf[stream->lp_idx].buf, s->s, MIN(s->len, RTP_LOOP_PROTECT)); + stream->lp_idx = (stream->lp_idx + 1) % RTP_LOOP_PACKETS; loop_ok: - mutex_unlock(&stream->in_lock); + mutex_unlock(&stream->in_lock); + } #endif