diff --git a/daemon/ice.c b/daemon/ice.c index eb3666196..9afc8d4ea 100644 --- a/daemon/ice.c +++ b/daemon/ice.c @@ -1396,3 +1396,24 @@ void ice_remote_candidates(GQueue *out, struct ice_agent *ag) { g_queue_clear(&all_compos); } + +bool ice_peer_address_known(struct ice_agent *ag, const endpoint_t *sin, struct packet_stream *ps, + const struct local_intf *ifa) +{ + mutex_lock(&ag->lock); + bool ret = false; + + struct ice_candidate *cand = __cand_lookup(ag, sin, ps->component); + if (!cand) + goto out; + struct ice_candidate_pair *pair = __pair_lookup(ag, cand, ifa); + if (!pair) + goto out; + if (!PAIR_ISSET(pair, VALID)) + goto out; + + ret = true; +out: + mutex_unlock(&ag->lock); + return ret; +} diff --git a/daemon/media_socket.c b/daemon/media_socket.c index dabdecea4..54d3a0ec4 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -1540,6 +1540,19 @@ static void __stream_ssrc(struct packet_stream *in_srtp, struct packet_stream *o // 1 = same as 0, but stream can be kernelized static int media_demux_protocols(struct packet_handler_ctx *phc) { if (MEDIA_ISSET(phc->mp.media, DTLS) && is_dtls(&phc->s)) { + // verify DTLS packet against ICE checks if present + if (MEDIA_ISSET(phc->mp.media, ICE) && phc->mp.media->ice_agent) { + if (!ice_peer_address_known(phc->mp.media->ice_agent, &phc->mp.fsin, phc->mp.stream, + phc->mp.sfd->local_intf)) + { + ilog(LOG_DEBUG, "Ignoring DTLS packet from %s%s%s to %s as no matching valid " + "ICE candidate pair exists", + FMT_M(endpoint_print_buf(&phc->mp.fsin)), + endpoint_print_buf(&phc->mp.sfd->socket.local)); + return 0; + } + } + mutex_lock(&phc->mp.stream->in_lock); int ret = dtls(phc->mp.sfd, &phc->s, &phc->mp.fsin); mutex_unlock(&phc->mp.stream->in_lock); diff --git a/include/ice.h b/include/ice.h index b9980bbbe..781265563 100644 --- a/include/ice.h +++ b/include/ice.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "str.h" #include "obj.h" #include "aux.h" @@ -150,6 +151,8 @@ void ice_free(void); enum ice_candidate_type ice_candidate_type(const str *s); int ice_has_related(enum ice_candidate_type); void ice_foundation(str *); +bool ice_peer_address_known(struct ice_agent *, const endpoint_t *, struct packet_stream *, + const struct local_intf *ifa); void ice_agent_init(struct ice_agent **agp, struct call_media *media); void ice_update(struct ice_agent *, struct stream_params *);