Browse Source

use str_token_sep for SDP token extraction

closes #472

Change-Id: I10dc4aa8baadfc4c3d5ef5514e47fecc4bf2f10e
changes/76/19376/1
Richard Fuchs 8 years ago
parent
commit
092f8da3c6
2 changed files with 32 additions and 54 deletions
  1. +32
    -53
      daemon/sdp.c
  2. +0
    -1
      lib/str.h

+ 32
- 53
daemon/sdp.c View File

@ -273,26 +273,7 @@ static int parse_address(struct network_address *address) {
&address->address_type, &address->address); &address->address_type, &address->address);
} }
INLINE int extract_token(char **sp, char *end, str *out) {
char *space;
out->s = *sp;
space = memchr(*sp, ' ', end - *sp);
if (space == *sp || end == *sp)
return -1;
if (!space) {
out->len = end - *sp;
*sp = end;
}
else {
out->len = space - *sp;
*sp = space + 1;
}
return 0;
}
#define EXTRACT_TOKEN(field) if (extract_token(&start, end, &output->field)) return -1
#define EXTRACT_TOKEN(field) if (str_token_sep(&output->field, value_str, ' ')) return -1
#define EXTRACT_NETWORK_ADDRESS_NP(field) \ #define EXTRACT_NETWORK_ADDRESS_NP(field) \
EXTRACT_TOKEN(field.network_type); \ EXTRACT_TOKEN(field.network_type); \
EXTRACT_TOKEN(field.address_type); \ EXTRACT_TOKEN(field.address_type); \
@ -307,10 +288,10 @@ INLINE int extract_token(char **sp, char *end, str *out) {
output->field.parsed.u.ipv4.s_addr = 1; \ output->field.parsed.u.ipv4.s_addr = 1; \
} while (0) } while (0)
#define PARSE_DECL char *end, *start
#define PARSE_INIT start = output->value.s; end = start + output->value.len
#define PARSE_DECL str v_str, *value_str
#define PARSE_INIT v_str = output->value; value_str = &v_str
static int parse_origin(char *start, char *end, struct sdp_origin *output) {
static int parse_origin(str *value_str, struct sdp_origin *output) {
if (output->parsed) if (output->parsed)
return -1; return -1;
@ -323,7 +304,7 @@ static int parse_origin(char *start, char *end, struct sdp_origin *output) {
return 0; return 0;
} }
static int parse_connection(char *start, char *end, struct sdp_connection *output) {
static int parse_connection(str *value_str, struct sdp_connection *output) {
if (output->parsed) if (output->parsed)
return -1; return -1;
@ -333,14 +314,14 @@ static int parse_connection(char *start, char *end, struct sdp_connection *outpu
return 0; return 0;
} }
static int parse_media(char *start, char *end, struct sdp_media *output) {
static int parse_media(str *value_str, struct sdp_media *output) {
char *ep; char *ep;
str s, *sp;
str *sp;
EXTRACT_TOKEN(media_type); EXTRACT_TOKEN(media_type);
EXTRACT_TOKEN(port); EXTRACT_TOKEN(port);
EXTRACT_TOKEN(transport); EXTRACT_TOKEN(transport);
str_init_len(&output->formats, start, end - start);
output->formats = *value_str;
output->port_num = strtol(output->port.s, &ep, 10); output->port_num = strtol(output->port.s, &ep, 10);
if (ep == output->port.s) if (ep == output->port.s)
@ -359,11 +340,11 @@ static int parse_media(char *start, char *end, struct sdp_media *output) {
output->port_count = 1; output->port_count = 1;
/* to split the "formats" list into tokens, we abuse some vars */ /* to split the "formats" list into tokens, we abuse some vars */
start = output->formats.s;
end = start + output->formats.len;
while (!extract_token(&start, end, &s)) {
str formats = output->formats;
str format;
while (!str_token_sep(&format, &formats, ' ')) {
sp = g_slice_alloc(sizeof(*sp)); sp = g_slice_alloc(sizeof(*sp));
*sp = s;
*sp = format;
g_queue_push_tail(&output->format_list, sp); g_queue_push_tail(&output->format_list, sp);
} }
@ -536,7 +517,7 @@ static int parse_attribute_crypto(struct sdp_attribute *output) {
memcpy(c->mki + (c->mki_len - sizeof(u32)), &u32, sizeof(u32)); memcpy(c->mki + (c->mki_len - sizeof(u32)), &u32, sizeof(u32));
} }
while (extract_token(&start, end, &s) == 0) {
while (str_token_sep(&s, value_str, ' ') == 0) {
if (!str_cmp(&s, "UNENCRYPTED_SRTCP")) if (!str_cmp(&s, "UNENCRYPTED_SRTCP"))
c->unencrypted_srtcp = 1; c->unencrypted_srtcp = 1;
else if (!str_cmp(&s, "UNENCRYPTED_SRTP")) else if (!str_cmp(&s, "UNENCRYPTED_SRTP"))
@ -554,27 +535,24 @@ error:
} }
static int parse_attribute_rtcp(struct sdp_attribute *output) { static int parse_attribute_rtcp(struct sdp_attribute *output) {
char *ep, *start, *end;
if (!output->value.s) if (!output->value.s)
goto err; goto err;
output->attr = ATTR_RTCP; output->attr = ATTR_RTCP;
end = output->value.s + output->value.len;
output->u.rtcp.port_num = strtol(output->value.s, &ep, 10);
if (ep == output->value.s)
PARSE_DECL;
PARSE_INIT;
str portnum;
if (str_token_sep(&portnum, value_str, ' '))
goto err; goto err;
output->u.rtcp.port_num = str_to_i(&portnum, 0);
if (output->u.rtcp.port_num <= 0 || output->u.rtcp.port_num > 0xffff) { if (output->u.rtcp.port_num <= 0 || output->u.rtcp.port_num > 0xffff) {
output->u.rtcp.port_num = 0; output->u.rtcp.port_num = 0;
goto err; goto err;
} }
if (*ep != ' ')
return 0;
ep++;
if (ep >= end)
return 0;
start = ep;
EXTRACT_NETWORK_ADDRESS(u.rtcp.address);
if (value_str->len)
EXTRACT_NETWORK_ADDRESS(u.rtcp.address);
return 0; return 0;
@ -774,19 +752,17 @@ static int parse_attribute_rtpmap(struct sdp_attribute *output) {
static int parse_attribute_fmtp(struct sdp_attribute *output) { static int parse_attribute_fmtp(struct sdp_attribute *output) {
PARSE_DECL; PARSE_DECL;
char *ep;
struct attribute_fmtp *a; struct attribute_fmtp *a;
output->attr = ATTR_FMTP; output->attr = ATTR_FMTP;
a = &output->u.fmtp;
PARSE_INIT; PARSE_INIT;
EXTRACT_TOKEN(u.fmtp.payload_type_str); EXTRACT_TOKEN(u.fmtp.payload_type_str);
EXTRACT_TOKEN(u.fmtp.format_parms_str);
a = &output->u.fmtp;
output->u.fmtp.format_parms_str = *value_str;
a->payload_type = strtoul(a->payload_type_str.s, &ep, 10);
if (ep == a->payload_type_str.s)
a->payload_type = str_to_i(&a->payload_type_str, -1);
if (a->payload_type == -1)
return -1; return -1;
return 0; return 0;
@ -942,6 +918,9 @@ int sdp_parse(str *body, GQueue *sessions) {
if (!session && b[0] != 'v') if (!session && b[0] != 'v')
goto error; goto error;
str value_str;
str_init_len(&value_str, value, line_end - value);
switch (b[0]) { switch (b[0]) {
case 'v': case 'v':
errstr = "Error in v= line"; errstr = "Error in v= line";
@ -965,7 +944,7 @@ int sdp_parse(str *body, GQueue *sessions) {
if (media) if (media)
goto error; goto error;
errstr = "Error parsing o= line"; errstr = "Error parsing o= line";
if (parse_origin(value, line_end, &session->origin))
if (parse_origin(&value_str, &session->origin))
goto error; goto error;
break; break;
@ -975,7 +954,7 @@ int sdp_parse(str *body, GQueue *sessions) {
media->session = session; media->session = session;
attrs_init(&media->attributes); attrs_init(&media->attributes);
errstr = "Error parsing m= line"; errstr = "Error parsing m= line";
if (parse_media(value, line_end, media))
if (parse_media(&value_str, media))
goto error; goto error;
g_queue_push_tail(&session->media_streams, media); g_queue_push_tail(&session->media_streams, media);
media->s.s = b; media->s.s = b;
@ -985,7 +964,7 @@ int sdp_parse(str *body, GQueue *sessions) {
case 'c': case 'c':
errstr = "Error parsing c= line"; errstr = "Error parsing c= line";
if (parse_connection(value, line_end,
if (parse_connection(&value_str,
media ? &media->connection : &session->connection)) media ? &media->connection : &session->connection))
goto error; goto error;


+ 0
- 1
lib/str.h View File

@ -309,7 +309,6 @@ INLINE unsigned int str_to_ui(str *s, int def) {
return ret; return ret;
} }
// XXX use this for sdp.c token extraction
INLINE int str_token(str *new_token, str *ori_and_remainder, int sep) { INLINE int str_token(str *new_token, str *ori_and_remainder, int sep) {
*new_token = *ori_and_remainder; *new_token = *ori_and_remainder;
if (!str_chr_str(ori_and_remainder, ori_and_remainder, sep)) if (!str_chr_str(ori_and_remainder, ori_and_remainder, sep))


Loading…
Cancel
Save