|
|
|
@ -540,7 +540,7 @@ static bool parse_address(struct network_address *address) { |
|
|
|
&address->address_type, &address->address); |
|
|
|
} |
|
|
|
|
|
|
|
#define EXTRACT_TOKEN(field) do { if (!str_token_sep(&output->field, value_str, ' ')) return -1; } while (0) |
|
|
|
#define EXTRACT_TOKEN(field) do { if (!str_token_sep(&output->field, value_str, ' ')) return false; } while (0) |
|
|
|
#define EXTRACT_TOKEN_EXCL_INCORRECT(field) \ |
|
|
|
do { \ |
|
|
|
if (!str_token_sep(&output->field, value_str, ' ')) \ |
|
|
|
@ -552,7 +552,7 @@ static bool parse_address(struct network_address *address) { |
|
|
|
EXTRACT_TOKEN(field.address); } while (0) |
|
|
|
#define EXTRACT_NETWORK_ADDRESS(field) \ |
|
|
|
do { EXTRACT_NETWORK_ADDRESS_NP(field); \ |
|
|
|
if (!parse_address(&output->field)) return -1; } while (0) |
|
|
|
if (!parse_address(&output->field)) return false; } while (0) |
|
|
|
#define EXTRACT_NETWORK_ADDRESS_ATTR(field) \ |
|
|
|
do { EXTRACT_NETWORK_ADDRESS_NP(field); \ |
|
|
|
if (!parse_address(&output->field)) goto error; } while (0) |
|
|
|
@ -565,9 +565,9 @@ static bool parse_address(struct network_address *address) { |
|
|
|
|
|
|
|
#define PARSE_INIT str v_str = output->strs.value; str *value_str = &v_str |
|
|
|
|
|
|
|
static int parse_origin(str *value_str, sdp_origin *output) { |
|
|
|
static bool parse_origin(str *value_str, sdp_origin *output) { |
|
|
|
if (output->parsed) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
|
|
|
|
EXTRACT_TOKEN(username); |
|
|
|
EXTRACT_TOKEN(session_id); |
|
|
|
@ -576,22 +576,22 @@ static int parse_origin(str *value_str, sdp_origin *output) { |
|
|
|
|
|
|
|
output->version_num = strtoull(output->version_str.s, NULL, 10); |
|
|
|
output->parsed = 1; |
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static int parse_connection(str *value_str, struct sdp_connection *output) { |
|
|
|
static bool parse_connection(str *value_str, struct sdp_connection *output) { |
|
|
|
if (output->parsed) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
|
|
|
|
output->s = *value_str; |
|
|
|
|
|
|
|
EXTRACT_NETWORK_ADDRESS(address); |
|
|
|
|
|
|
|
output->parsed = 1; |
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static int parse_media(str *value_str, struct sdp_media *output) { |
|
|
|
static bool parse_media(str *value_str, struct sdp_media *output) { |
|
|
|
char *ep; |
|
|
|
str *sp; |
|
|
|
|
|
|
|
@ -603,16 +603,16 @@ static int parse_media(str *value_str, struct sdp_media *output) { |
|
|
|
output->media_type_id = codec_get_type(&output->media_type_str); |
|
|
|
output->port_num = strtol(output->port.s, &ep, 10); |
|
|
|
if (ep == output->port.s) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
if (output->port_num < 0 || output->port_num > 0xffff) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
|
|
|
|
if (*ep == '/') { |
|
|
|
output->port_count = atoi(ep + 1); |
|
|
|
if (output->port_count <= 0) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
if (output->port_count > 10) /* unsupported */ |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
} |
|
|
|
else |
|
|
|
output->port_count = 1; |
|
|
|
@ -625,7 +625,7 @@ static int parse_media(str *value_str, struct sdp_media *output) { |
|
|
|
t_queue_push_tail(&output->format_list, sp); |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static void attrs_init(struct sdp_attributes *a) { |
|
|
|
@ -656,17 +656,17 @@ static void attr_insert(struct sdp_attributes *attrs, struct sdp_attribute *attr |
|
|
|
g_queue_push_tail(attr_queue, attr); */ |
|
|
|
} |
|
|
|
|
|
|
|
static int parse_attribute_group(struct sdp_attribute *output) { |
|
|
|
static bool parse_attribute_group(struct sdp_attribute *output) { |
|
|
|
output->attr = ATTR_GROUP; |
|
|
|
|
|
|
|
output->group.semantics = GROUP_OTHER; |
|
|
|
if (output->strs.value.len >= 7 && !strncmp(output->strs.value.s, "BUNDLE ", 7)) |
|
|
|
output->group.semantics = GROUP_BUNDLE; |
|
|
|
|
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static int parse_attribute_crypto(struct sdp_attribute *output) { |
|
|
|
static bool parse_attribute_crypto(struct sdp_attribute *output) { |
|
|
|
char *endp; |
|
|
|
struct attribute_crypto *c; |
|
|
|
int salt_key_len, enc_salt_key_len; |
|
|
|
@ -793,17 +793,17 @@ static int parse_attribute_crypto(struct sdp_attribute *output) { |
|
|
|
c->unauthenticated_srtp = 1; |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
|
|
|
|
error: |
|
|
|
if (!err) |
|
|
|
err = "generic error"; |
|
|
|
ilog(LOG_ERROR, "Failed to parse a=crypto attribute, ignoring: %s", err); |
|
|
|
output->attr = ATTR_IGNORE; |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
static int parse_attribute_rtcp(struct sdp_attribute *output) { |
|
|
|
static bool parse_attribute_rtcp(struct sdp_attribute *output) { |
|
|
|
if (!output->strs.value.s) |
|
|
|
goto error; |
|
|
|
output->attr = ATTR_RTCP; |
|
|
|
@ -822,15 +822,15 @@ static int parse_attribute_rtcp(struct sdp_attribute *output) { |
|
|
|
if (value_str->len) |
|
|
|
EXTRACT_NETWORK_ADDRESS_ATTR(rtcp.address); |
|
|
|
|
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
|
|
|
|
error: |
|
|
|
ilog(LOG_WARN, "Failed to parse a=rtcp attribute, ignoring"); |
|
|
|
output->attr = ATTR_IGNORE; |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
static int parse_attribute_candidate(struct sdp_attribute *output, bool extended) { |
|
|
|
static bool parse_attribute_candidate(struct sdp_attribute *output, bool extended) { |
|
|
|
char *ep; |
|
|
|
struct attribute_candidate *c; |
|
|
|
|
|
|
|
@ -849,29 +849,29 @@ static int parse_attribute_candidate(struct sdp_attribute *output, bool extended |
|
|
|
|
|
|
|
c->cand_parsed.component_id = strtoul(c->component_str.s, &ep, 10); |
|
|
|
if (ep == c->component_str.s) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
|
|
|
|
c->cand_parsed.transport = get_socket_type(&c->transport_str); |
|
|
|
if (!c->cand_parsed.transport) |
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
|
|
|
|
c->cand_parsed.priority = strtoul(c->priority_str.s, &ep, 10); |
|
|
|
if (ep == c->priority_str.s) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
|
|
|
|
if (!sockaddr_parse_any_str(&c->cand_parsed.endpoint.address, &c->address_str)) |
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
|
|
|
|
c->cand_parsed.endpoint.port = strtoul(c->port_str.s, &ep, 10); |
|
|
|
if (ep == c->port_str.s) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
|
|
|
|
if (str_cmp(&c->typ_str, "typ")) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
|
|
|
|
c->cand_parsed.type = ice_candidate_type(&c->type_str); |
|
|
|
if (!c->cand_parsed.type) |
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
|
|
|
|
if (ice_has_related(c->cand_parsed.type)) { |
|
|
|
// XXX guaranteed to be in order even with extended syntax? |
|
|
|
@ -881,16 +881,16 @@ static int parse_attribute_candidate(struct sdp_attribute *output, bool extended |
|
|
|
EXTRACT_TOKEN(candidate.related_port_str); |
|
|
|
|
|
|
|
if (str_cmp(&c->raddr_str, "raddr")) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
if (str_cmp(&c->rport_str, "rport")) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
|
|
|
|
if (!sockaddr_parse_any_str(&c->cand_parsed.related.address, &c->related_address_str)) |
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
|
|
|
|
c->cand_parsed.related.port = strtoul(c->related_port_str.s, &ep, 10); |
|
|
|
if (ep == c->related_port_str.s) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
if (extended) { |
|
|
|
@ -906,7 +906,7 @@ static int parse_attribute_candidate(struct sdp_attribute *output, bool extended |
|
|
|
} |
|
|
|
|
|
|
|
c->parsed = 1; |
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
// 0 = success |
|
|
|
@ -919,7 +919,7 @@ int sdp_parse_candidate(struct ice_candidate *cand, const str *s) { |
|
|
|
}, |
|
|
|
}; |
|
|
|
|
|
|
|
if (parse_attribute_candidate(&attr, true)) |
|
|
|
if (!parse_attribute_candidate(&attr, true)) |
|
|
|
return -1; |
|
|
|
if (!attr.candidate.parsed) |
|
|
|
return 1; |
|
|
|
@ -929,7 +929,7 @@ int sdp_parse_candidate(struct ice_candidate *cand, const str *s) { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int parse_attribute_fingerprint(struct sdp_attribute *output) { |
|
|
|
static bool parse_attribute_fingerprint(struct sdp_attribute *output) { |
|
|
|
unsigned char *c; |
|
|
|
int i; |
|
|
|
|
|
|
|
@ -941,7 +941,7 @@ static int parse_attribute_fingerprint(struct sdp_attribute *output) { |
|
|
|
|
|
|
|
output->fingerprint.hash_func = dtls_find_hash_func(&output->fingerprint.hash_func_str); |
|
|
|
if (!output->fingerprint.hash_func) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
|
|
|
|
assert(sizeof(output->fingerprint.fingerprint) >= output->fingerprint.hash_func->num_bytes); |
|
|
|
|
|
|
|
@ -954,7 +954,7 @@ static int parse_attribute_fingerprint(struct sdp_attribute *output) { |
|
|
|
else if (c[0] >= 'A' && c[0] <= 'F') |
|
|
|
output->fingerprint.fingerprint[i] = c[0] - 'A' + 10; |
|
|
|
else |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
|
|
|
|
output->fingerprint.fingerprint[i] <<= 4; |
|
|
|
|
|
|
|
@ -965,7 +965,7 @@ static int parse_attribute_fingerprint(struct sdp_attribute *output) { |
|
|
|
else if (c[1] >= 'A' && c[1] <= 'F') |
|
|
|
output->fingerprint.fingerprint[i] |= c[1] - 'A' + 10; |
|
|
|
else |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
|
|
|
|
if (c[2] != ':') |
|
|
|
goto done; |
|
|
|
@ -973,16 +973,16 @@ static int parse_attribute_fingerprint(struct sdp_attribute *output) { |
|
|
|
c += 3; |
|
|
|
} |
|
|
|
|
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
|
|
|
|
done: |
|
|
|
if (++i != output->fingerprint.hash_func->num_bytes) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
|
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static int parse_attribute_setup(struct sdp_attribute *output) { |
|
|
|
static bool parse_attribute_setup(struct sdp_attribute *output) { |
|
|
|
output->attr = ATTR_SETUP; |
|
|
|
|
|
|
|
if (!str_cmp(&output->strs.value, "actpass")) |
|
|
|
@ -994,10 +994,10 @@ static int parse_attribute_setup(struct sdp_attribute *output) { |
|
|
|
else if (!str_cmp(&output->strs.value, "holdconn")) |
|
|
|
output->setup.value = SETUP_HOLDCONN; |
|
|
|
|
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static int parse_attribute_rtcp_fb(struct sdp_attribute *output) { |
|
|
|
static bool parse_attribute_rtcp_fb(struct sdp_attribute *output) { |
|
|
|
struct attribute_rtcp_fb *a; |
|
|
|
|
|
|
|
output->attr = ATTR_RTCP_FB; |
|
|
|
@ -1012,13 +1012,13 @@ static int parse_attribute_rtcp_fb(struct sdp_attribute *output) { |
|
|
|
else { |
|
|
|
a->payload_type = str_to_i(&a->payload_type_str, -1); |
|
|
|
if (a->payload_type == -1) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static int parse_attribute_rtpmap(struct sdp_attribute *output) { |
|
|
|
static bool parse_attribute_rtpmap(struct sdp_attribute *output) { |
|
|
|
char *ep; |
|
|
|
struct attribute_rtpmap *a; |
|
|
|
rtp_payload_type *pt; |
|
|
|
@ -1036,10 +1036,10 @@ static int parse_attribute_rtpmap(struct sdp_attribute *output) { |
|
|
|
|
|
|
|
pt->payload_type = strtoul(a->payload_type_str.s, &ep, 10); |
|
|
|
if (ep == a->payload_type_str.s) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
|
|
|
|
if (!str_chr_str(&a->clock_rate_str, &a->encoding_str, '/')) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
|
|
|
|
pt->encoding = a->encoding_str; |
|
|
|
pt->encoding.len -= a->clock_rate_str.len; |
|
|
|
@ -1058,16 +1058,16 @@ static int parse_attribute_rtpmap(struct sdp_attribute *output) { |
|
|
|
} |
|
|
|
|
|
|
|
if (!a->clock_rate_str.len) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
|
|
|
|
pt->clock_rate = strtoul(a->clock_rate_str.s, &ep, 10); |
|
|
|
if (ep && ep != a->clock_rate_str.s + a->clock_rate_str.len) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
|
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static int parse_attribute_fmtp(struct sdp_attribute *output) { |
|
|
|
static bool parse_attribute_fmtp(struct sdp_attribute *output) { |
|
|
|
struct attribute_fmtp *a; |
|
|
|
|
|
|
|
output->attr = ATTR_FMTP; |
|
|
|
@ -1079,19 +1079,19 @@ static int parse_attribute_fmtp(struct sdp_attribute *output) { |
|
|
|
|
|
|
|
a->payload_type = str_to_i(&a->payload_type_str, -1); |
|
|
|
if (a->payload_type == -1) |
|
|
|
return -1; |
|
|
|
return false; |
|
|
|
|
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static int parse_attribute_int(struct sdp_attribute *output, enum attr_id attr_id, int defval) { |
|
|
|
static bool parse_attribute_int(struct sdp_attribute *output, enum attr_id attr_id, int defval) { |
|
|
|
output->attr = attr_id; |
|
|
|
output->i = str_to_i(&output->strs.value, defval); |
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
// XXX combine this with parse_attribute_setup ? |
|
|
|
static int parse_attribute_t38faxudpec(struct sdp_attribute *output) { |
|
|
|
static bool parse_attribute_t38faxudpec(struct sdp_attribute *output) { |
|
|
|
output->attr = ATTR_T38FAXUDPEC; |
|
|
|
|
|
|
|
switch (__csh_lookup(&output->strs.value)) { |
|
|
|
@ -1109,11 +1109,11 @@ static int parse_attribute_t38faxudpec(struct sdp_attribute *output) { |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
// XXX combine this with parse_attribute_setup ? |
|
|
|
static int parse_attribute_t38faxratemanagement(struct sdp_attribute *output) { |
|
|
|
static bool parse_attribute_t38faxratemanagement(struct sdp_attribute *output) { |
|
|
|
output->attr = ATTR_T38FAXRATEMANAGEMENT; |
|
|
|
|
|
|
|
switch (__csh_lookup(&output->strs.value)) { |
|
|
|
@ -1128,10 +1128,10 @@ static int parse_attribute_t38faxratemanagement(struct sdp_attribute *output) { |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static int parse_attribute_t38faxudpecdepth(struct sdp_attribute *output) { |
|
|
|
static bool parse_attribute_t38faxudpecdepth(struct sdp_attribute *output) { |
|
|
|
struct attribute_t38faxudpecdepth *a; |
|
|
|
|
|
|
|
output->attr = ATTR_T38FAXUDPECDEPTH; |
|
|
|
@ -1144,13 +1144,11 @@ static int parse_attribute_t38faxudpecdepth(struct sdp_attribute *output) { |
|
|
|
a->minred = str_to_i(&a->minred_str, 0); |
|
|
|
a->maxred = str_to_i(&a->maxred_str, -1); |
|
|
|
|
|
|
|
return 0; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int parse_attribute(struct sdp_attribute *a) { |
|
|
|
int ret; |
|
|
|
|
|
|
|
static bool parse_attribute(struct sdp_attribute *a) { |
|
|
|
a->strs.name = a->strs.line_value; |
|
|
|
if (str_chr_str(&a->strs.value, &a->strs.name, ':')) { |
|
|
|
a->strs.name.len -= a->strs.value.len; |
|
|
|
@ -1172,7 +1170,7 @@ static int parse_attribute(struct sdp_attribute *a) { |
|
|
|
a->strs.key.len += 1 + a->strs.value.len; |
|
|
|
} |
|
|
|
|
|
|
|
ret = 0; |
|
|
|
bool ret = true; |
|
|
|
switch (__csh_lookup(&a->strs.name)) { |
|
|
|
case CSH_LOOKUP("mid"): |
|
|
|
a->attr = ATTR_MID; |
|
|
|
@ -1367,7 +1365,7 @@ new_session: |
|
|
|
if (media) |
|
|
|
goto error; |
|
|
|
errstr = "Error parsing o= line"; |
|
|
|
if (parse_origin(&value, &session->origin)) |
|
|
|
if (!parse_origin(&value, &session->origin)) |
|
|
|
goto error; |
|
|
|
|
|
|
|
break; |
|
|
|
@ -1377,7 +1375,7 @@ new_session: |
|
|
|
media->session = session; |
|
|
|
attrs_init(&media->attributes); |
|
|
|
errstr = "Error parsing m= line"; |
|
|
|
if (parse_media(&value, media)) |
|
|
|
if (!parse_media(&value, media)) |
|
|
|
goto error; |
|
|
|
t_queue_push_tail(&session->media_streams, media); |
|
|
|
media->s = full_line; |
|
|
|
@ -1387,7 +1385,7 @@ new_session: |
|
|
|
|
|
|
|
case 'c': |
|
|
|
errstr = "Error parsing c= line"; |
|
|
|
if (parse_connection(&value, |
|
|
|
if (!parse_connection(&value, |
|
|
|
media ? &media->connection : &session->connection)) |
|
|
|
goto error; |
|
|
|
|
|
|
|
@ -1399,7 +1397,7 @@ new_session: |
|
|
|
attr->full_line = full_line; |
|
|
|
attr->strs.line_value = value; |
|
|
|
|
|
|
|
if (parse_attribute(attr)) { |
|
|
|
if (!parse_attribute(attr)) { |
|
|
|
attr_free(attr); |
|
|
|
break; |
|
|
|
} |
|
|
|
|