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