From b0c97e4ccccfa1bcb045730c0b70fdef189df30d Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 15 Jul 2021 15:01:22 -0400 Subject: [PATCH] TT#89352 support extended ICE candidate syntax Change-Id: Ib0d116d69297459a0ec8e3c06f5497df4bb7dbfb --- daemon/ice.c | 6 ++--- daemon/sdp.c | 63 ++++++++++++++++++++++++++++++++++++--------------- include/ice.h | 4 +++- include/sdp.h | 4 ++++ 4 files changed, 55 insertions(+), 22 deletions(-) diff --git a/daemon/ice.c b/daemon/ice.c index c2b329e79..0437cdccb 100644 --- a/daemon/ice.c +++ b/daemon/ice.c @@ -90,11 +90,11 @@ enum ice_candidate_type ice_candidate_type(const str *s) { return ICT_UNKNOWN; } -int ice_has_related(enum ice_candidate_type t) { +bool ice_has_related(enum ice_candidate_type t) { if (t == ICT_HOST) - return 0; + return false; /* ignoring ICT_UNKNOWN */ - return 1; + return true; } diff --git a/daemon/sdp.c b/daemon/sdp.c index 89abe103b..8d6a54f03 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "compat.h" #include "call.h" @@ -621,7 +622,7 @@ err: return 0; } -static int parse_attribute_candidate(struct sdp_attribute *output) { +static int parse_attribute_candidate(struct sdp_attribute *output, bool extended) { PARSE_DECL; char *ep; struct attribute_candidate *c; @@ -665,31 +666,57 @@ static int parse_attribute_candidate(struct sdp_attribute *output) { if (!c->cand_parsed.type) return 0; - if (!ice_has_related(c->cand_parsed.type)) - goto done; + if (ice_has_related(c->cand_parsed.type)) { + // XXX guaranteed to be in order even with extended syntax? + EXTRACT_TOKEN(u.candidate.raddr_str); + EXTRACT_TOKEN(u.candidate.related_address_str); + EXTRACT_TOKEN(u.candidate.rport_str); + EXTRACT_TOKEN(u.candidate.related_port_str); - EXTRACT_TOKEN(u.candidate.raddr_str); - EXTRACT_TOKEN(u.candidate.related_address_str); - EXTRACT_TOKEN(u.candidate.rport_str); - EXTRACT_TOKEN(u.candidate.related_port_str); + if (str_cmp(&c->raddr_str, "raddr")) + return -1; + if (str_cmp(&c->rport_str, "rport")) + return -1; - if (str_cmp(&c->raddr_str, "raddr")) - return -1; - if (str_cmp(&c->rport_str, "rport")) - return -1; + if (__parse_address(&c->cand_parsed.related.address, NULL, NULL, &c->related_address_str)) + return 0; - if (__parse_address(&c->cand_parsed.related.address, NULL, NULL, &c->related_address_str)) - return 0; + c->cand_parsed.related.port = strtoul(c->related_port_str.s, &ep, 10); + if (ep == c->related_port_str.s) + return -1; + } - c->cand_parsed.related.port = strtoul(c->related_port_str.s, &ep, 10); - if (ep == c->related_port_str.s) - return -1; + if (extended) { + while (true) { + str field, value; + if (str_token_sep(&field, value_str, ' ')) + break; + if (str_token_sep(&value, value_str, ' ')) + break; + if (!str_cmp(&field, "ufrag")) + c->cand_parsed.ufrag = value; + } + } -done: c->parsed = 1; return 0; } +int sdp_parse_candidate(struct ice_candidate *cand, const str *s) { + struct sdp_attribute attr = { + .value = *s, + }; + + if (parse_attribute_candidate(&attr, true)) + return -1; + if (!attr.u.candidate.parsed) + return -1; + *cand = attr.u.candidate.cand_parsed; + + return 0; +} + + static int parse_attribute_fingerprint(struct sdp_attribute *output) { PARSE_DECL; unsigned char *c; @@ -992,7 +1019,7 @@ static int parse_attribute(struct sdp_attribute *a) { a->attr = ATTR_RTCP_MUX; break; case CSH_LOOKUP("candidate"): - ret = parse_attribute_candidate(a); + ret = parse_attribute_candidate(a, false); break; case CSH_LOOKUP("ice-ufrag"): a->attr = ATTR_ICE_UFRAG; diff --git a/include/ice.h b/include/ice.h index d2a52a4f1..f08f7fd52 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" @@ -86,6 +87,7 @@ struct ice_candidate { endpoint_t endpoint; enum ice_candidate_type type; endpoint_t related; + str ufrag; }; struct ice_candidate_pair { @@ -147,7 +149,7 @@ void ice_init(void); void ice_free(void); enum ice_candidate_type ice_candidate_type(const str *s); -int ice_has_related(enum ice_candidate_type); +bool ice_has_related(enum ice_candidate_type); void ice_foundation(str *); void ice_agent_init(struct ice_agent **agp, struct call_media *media); diff --git a/include/sdp.h b/include/sdp.h index e5ac63fd6..e8c8491fd 100644 --- a/include/sdp.h +++ b/include/sdp.h @@ -7,6 +7,8 @@ #include "media_socket.h" +struct ice_candidate; + struct sdp_chopper { str *input; size_t position; @@ -26,6 +28,8 @@ int sdp_replace(struct sdp_chopper *, GQueue *, struct call_monologue *, struct int sdp_is_duplicate(GQueue *sessions); int sdp_create(str *out, struct call_monologue *, struct sdp_ng_flags *flags); +int sdp_parse_candidate(struct ice_candidate *cand, const str *s); + struct sdp_chopper *sdp_chopper_new(str *input); void sdp_chopper_destroy(struct sdp_chopper *chop);