diff --git a/daemon/ice.c b/daemon/ice.c index ee0f8e59d..153b1f6c8 100644 --- a/daemon/ice.c +++ b/daemon/ice.c @@ -1396,3 +1396,20 @@ 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) +{ + LOCK(&ag->lock); + + struct ice_candidate *cand = __cand_lookup(ag, sin, ps->component); + if (!cand) + return false; + struct ice_candidate_pair *pair = __pair_lookup(ag, cand, ifa); + if (!pair) + return false; + if (!PAIR_ISSET(pair, VALID)) + return false; + + return true; +} diff --git a/daemon/media_socket.c b/daemon/media_socket.c index d21929d09..7778db624 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -1759,6 +1759,19 @@ static bool __stream_ssrc_out(struct packet_stream *out_srtp, uint32_t ssrc_bs, // 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 90d758a00..836d044fa 100644 --- a/include/ice.h +++ b/include/ice.h @@ -152,6 +152,8 @@ void ice_free(void); enum ice_candidate_type ice_candidate_type(const str *s); bool 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 *, bool allow_restart);