diff --git a/daemon/call.c b/daemon/call.c index 6ead4cd97..000afbba3 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -2839,6 +2839,7 @@ static void __media_init_from_flags(struct call_media *other_media, struct call_ bf_copy_same(&other_media->media_flags, &sp->sp_flags, SHARED_FLAG_RTCP_MUX | SHARED_FLAG_ASYMMETRIC | SHARED_FLAG_UNIDIRECTIONAL | SHARED_FLAG_ICE | SHARED_FLAG_TRICKLE_ICE | SHARED_FLAG_ICE_LITE_PEER | + SHARED_FLAG_END_OF_CANDIDATES | SHARED_FLAG_RTCP_FB | SHARED_FLAG_LEGACY_OSRTP | SHARED_FLAG_LEGACY_OSRTP_REV); // duplicate the entire queue of offered crypto params diff --git a/daemon/sdp.c b/daemon/sdp.c index e25a9802c..da71859d4 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -1568,6 +1568,7 @@ static void __sdp_ice(struct stream_params *sp, struct sdp_media *media) { struct sdp_attribute *attr; struct attribute_candidate *ac; struct ice_candidate *cand; + bool end_of_candidates = (attr_get_by_id_m_s(media, ATTR_END_OF_CANDIDATES)); attr = attr_get_by_id_m_s(media, ATTR_ICE_UFRAG); if (!attr) @@ -1598,6 +1599,13 @@ no_cand: else if (is_trickle_ice_address(&sp->rtp_endpoint)) SP_SET(sp, TRICKLE_ICE); + /* set end_of_candidates flag both, when it's trickle ice or not */ + if (end_of_candidates) + SP_SET(sp, END_OF_CANDIDATES); + /* unset end_of_candidates flag, if it's non trickle and no attribute given */ + if (!SP_ISSET(sp, TRICKLE_ICE) && !end_of_candidates) + SP_CLEAR(sp, END_OF_CANDIDATES); + if (attr_get_by_id_m_s(media, ATTR_ICE_LITE)) SP_SET(sp, ICE_LITE_PEER); @@ -2108,6 +2116,10 @@ void sdp_insert_monologue_attributes(GString *gs, union sdp_attr_print_arg a, co void sdp_insert_all_attributes(GString *s, struct call_media *media, struct sdp_ng_flags *flags) { for (__auto_type l = media->all_attributes.head; l; l = l->next) { __auto_type a = l->data; + // the one exception: skip this and then print it separately if it was present, + // so that we can print our own candidates first + if (a->attr == ATTR_END_OF_CANDIDATES) + continue; append_str_attr_to_gstring(s, &a->strs.name, &a->strs.value, flags, media->type_id); } } @@ -3007,6 +3019,8 @@ static void sdp_out_original_media_attributes(GString *out, struct call_media *m if (rtcp_ps && (!rtcp_ps->selected_sfd || rtcp_ps->selected_sfd->socket.local.port == 0)) rtcp_ps = NULL; insert_candidates(out, rtp_ps, rtcp_ps, flags, source_media); + if (MEDIA_ISSET(source_media, END_OF_CANDIDATES)) + append_attr_to_gstring(out, "end-of-candidates", NULL, flags, media->type_id); } } diff --git a/include/call.h b/include/call.h index 7e5cbbc9b..65c40e0b1 100644 --- a/include/call.h +++ b/include/call.h @@ -139,6 +139,8 @@ enum { #define SHARED_FLAG_RTCP_FB 0x00002000 #define SHARED_FLAG_LEGACY_OSRTP 0x00004000 #define SHARED_FLAG_LEGACY_OSRTP_REV 0x00008000 +/* empty range in-between */ +#define SHARED_FLAG_END_OF_CANDIDATES 0x40000000LL /* struct stream_params */ #define SP_FLAG_NO_RTCP 0x00010000 @@ -158,6 +160,7 @@ enum { #define SP_FLAG_RTCP_FB SHARED_FLAG_RTCP_FB #define SP_FLAG_LEGACY_OSRTP SHARED_FLAG_LEGACY_OSRTP #define SP_FLAG_LEGACY_OSRTP_REV SHARED_FLAG_LEGACY_OSRTP_REV +#define SP_FLAG_END_OF_CANDIDATES SHARED_FLAG_END_OF_CANDIDATES /* struct packet_stream */ #define PS_FLAG_RTP 0x00010000 @@ -209,6 +212,7 @@ enum { #define MEDIA_FLAG_LEGACY_OSRTP_REV SHARED_FLAG_LEGACY_OSRTP_REV #define MEDIA_FLAG_TRANSCODING 0x100000000LL #define MEDIA_FLAG_BLOCK_EGRESS 0x200000000LL +#define MEDIA_FLAG_END_OF_CANDIDATES SHARED_FLAG_END_OF_CANDIDATES /* struct call_monologue */ #define ML_FLAG_REC_FORWARDING 0x00010000