Browse Source

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
changes/10/8510/1
Richard Fuchs 9 years ago
parent
commit
94e3c8f9cb
3 changed files with 31 additions and 39 deletions
  1. +7
    -17
      daemon/call.c
  2. +1
    -1
      daemon/call.h
  3. +23
    -21
      daemon/media_socket.c

+ 7
- 17
daemon/call.c View File

@ -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) { static void __endpoint_loop_protect(struct stream_params *sp, struct call_media *media) {
struct intf_address intf_addr; struct intf_address intf_addr;
struct packet_stream *ps;
/* check if the advertised endpoint is one of our own addresses. this can /* 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 * 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; intf_addr.type = socktype_udp;
// if (other_media->protocol && other_media->protocol->tcp) // 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)) if (!is_local_endpoint(&intf_addr, sp->rtp_endpoint.port))
return; 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 */ /* called with call->master_lock held in W */


+ 1
- 1
daemon/call.h View File

@ -93,7 +93,6 @@ enum call_type {
#define RTP_BUFFER_TAIL_ROOM 512 #define RTP_BUFFER_TAIL_ROOM 512
#define RTP_BUFFER_SIZE (MAX_RTP_PACKET_SIZE + RTP_BUFFER_HEAD_ROOM + RTP_BUFFER_TAIL_ROOM) #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 #ifndef RTP_LOOP_PROTECT
#define RTP_LOOP_PROTECT 28 /* number of bytes */ #define RTP_LOOP_PROTECT 28 /* number of bytes */
#define RTP_LOOP_PACKETS 2 /* number of packets */ #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_TRICKLE_ICE SHARED_FLAG_TRICKLE_ICE
#define MEDIA_FLAG_ICE_LITE SHARED_FLAG_ICE_LITE #define MEDIA_FLAG_ICE_LITE SHARED_FLAG_ICE_LITE
#define MEDIA_FLAG_ICE_CONTROLLING 0x00200000 #define MEDIA_FLAG_ICE_CONTROLLING 0x00200000
#define MEDIA_FLAG_LOOP_CHECK 0x00400000
/* access macros */ /* access macros */
#define SP_ISSET(p, f) bf_isset(&(p)->sp_flags, SP_FLAG_ ## f) #define SP_ISSET(p, f) bf_isset(&(p)->sp_flags, SP_FLAG_ ## f)


+ 23
- 21
daemon/media_socket.c View File

@ -1126,32 +1126,34 @@ static int stream_packet(struct stream_fd *sfd, str *s, const endpoint_t *fsin,
} }
#if RTP_LOOP_PROTECT #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: loop_ok:
mutex_unlock(&stream->in_lock);
mutex_unlock(&stream->in_lock);
}
#endif #endif


Loading…
Cancel
Save