int nr_ice_peer_ctx_parse_media_stream_attribute(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *attr) { int r,_status; char *orig = 0; char *str; orig = str = attr; if (!strncasecmp(str, "ice-ufrag:", 10)) { fast_forward(&str, 10); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if ((r=grab_token(&str, &stream->ufrag))) ABORT(r); } else if (!strncasecmp(str, "ice-pwd:", 8)) { fast_forward(&str, 8); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if ((r=grab_token(&str, &stream->pwd))) ABORT(r); } else { ABORT(R_BAD_DATA); } skip_whitespace(&str); /* RFC 5245 grammar doesn't have an extension point for ice-pwd or ice-ufrag: if there's anything left on the line, we treat it as bad. */ if (str[0] != '\0') { ABORT(R_BAD_DATA); } _status=0; abort: if (_status) { if (orig) r_log(LOG_ICE,LOG_WARNING,"ICE-PEER(%s): Error parsing attribute: %s",pctx->label,orig); } return(_status); }
int nr_ice_peer_ctx_parse_media_stream_attribute(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *attr) { int r,_status; char *orig = 0; char *str; orig = str = attr; if (!strncasecmp(str, "ice-ufrag:", 10)) { fast_forward(&str, 10); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if ((r=grab_token(&str, &stream->ufrag))) ABORT(r); } else if (!strncasecmp(str, "ice-pwd:", 8)) { fast_forward(&str, 8); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if ((r=grab_token(&str, &stream->pwd))) ABORT(r); } else { ABORT(R_BAD_DATA); } skip_whitespace(&str); /* it's expected to be at EOD at this point */ assert(strlen(str) == 0); _status=0; abort: if (_status) { if (orig) r_log(LOG_ICE,LOG_WARNING,"ICE-PEER(%s): Error parsing attribute: %s",pctx->label,orig); } return(_status); }
int nr_ice_peer_ctx_parse_global_attributes(nr_ice_peer_ctx *pctx, char **attrs, int attr_ct) { int r,_status; int i; char *orig = 0; char *str; char *component_id; char *connection_address; unsigned int port; in_addr_t addr; char *ice_option_tag; for(i=0;i<attr_ct;i++){ orig = str = attrs[i]; component_id = 0; connection_address = 0; ice_option_tag = 0; if (!strncasecmp(str, "remote-candidates:", 18)) { fast_forward(&str, 18); skip_whitespace(&str); while (*str != '\0') { if ((r=grab_token(&str, &component_id))) ABORT(r); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if ((r=grab_token(&str, &connection_address))) ABORT(r); if (*str == '\0') ABORT(R_BAD_DATA); addr = inet_addr(connection_address); if (addr == INADDR_NONE) ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if (sscanf(str, "%u", &port) != 1) ABORT(R_BAD_DATA); if (port < 1 || port > 0x0FFFF) ABORT(R_BAD_DATA); skip_to_past_space(&str); #if 0 /* TODO: !nn! just drop on the floor for now, later put somewhere */ /* Assume v4 for now */ if(r=nr_ip4_port_to_transport_addr(ntohl(addr),port,IPPROTO_UDP,&candidate->base)) ABORT(r); TAILQ_INSERT_TAIL(head, elm, field); #endif component_id = 0; /* prevent free */ RFREE(connection_address); connection_address = 0; /* prevent free */ } } else if (!strncasecmp(str, "ice-lite", 8)) { pctx->peer_lite = 1; fast_forward(&str, 8); } else if (!strncasecmp(str, "ice-mismatch", 12)) { pctx->peer_ice_mismatch = 1; fast_forward(&str, 12); } else if (!strncasecmp(str, "ice-ufrag:", 10)) { fast_forward(&str, 10); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if ((r=grab_token(&str, &pctx->peer_ufrag))) ABORT(r); } else if (!strncasecmp(str, "ice-pwd:", 8)) { fast_forward(&str, 8); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if ((r=grab_token(&str, &pctx->peer_pwd))) ABORT(r); } else if (!strncasecmp(str, "ice-options:", 12)) { fast_forward(&str, 12); skip_whitespace(&str); while (*str != '\0') { if ((r=grab_token(&str, &ice_option_tag))) ABORT(r); skip_whitespace(&str); #if 0 //TODO: !nn! for now, just drop on the floor, later put somewhere #endif ice_option_tag = 0; /* prevent free */ } } else { ABORT(R_BAD_DATA); } skip_whitespace(&str); /* it's expected to be at EOD at this point */ assert(strlen(str) == 0); } _status=0; abort: if (_status) { if (orig) r_log(LOG_ICE,LOG_WARNING,"ICE-PEER(%s): Error parsing attribute: %s",pctx->label,orig); } RFREE(connection_address); RFREE(component_id); RFREE(ice_option_tag); return(_status); }
int nr_ice_peer_candidate_from_attribute(nr_ice_ctx *ctx,char *orig,nr_ice_media_stream *stream,nr_ice_candidate **candp) { int r,_status; char* str = orig; nr_ice_candidate *cand; char *connection_address=0; unsigned int port; in_addr_t addr; int i; unsigned int component_id; char *rel_addr=0; if(!(cand=RCALLOC(sizeof(nr_ice_candidate)))) ABORT(R_NO_MEMORY); if(!(cand->label=r_strdup(orig))) ABORT(R_NO_MEMORY); cand->ctx=ctx; cand->isock=0; cand->state=NR_ICE_CAND_PEER_CANDIDATE; cand->stream=stream; skip_whitespace(&str); /* Candidate attr */ if (strncasecmp(str, "candidate:", 10)) ABORT(R_BAD_DATA); fast_forward(&str, 10); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); /* Foundation */ if ((r=grab_token(&str, &cand->foundation))) ABORT(r); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); /* component */ if (sscanf(str, "%u", &component_id) != 1) ABORT(R_BAD_DATA); if (component_id < 1 || component_id > 256) ABORT(R_BAD_DATA); cand->component_id = (UCHAR)component_id; skip_to_past_space(&str); if (*str == '\0') ABORT(R_BAD_DATA); /* Protocol */ if (strncasecmp(str, "UDP", 3)) ABORT(R_BAD_DATA); fast_forward(&str, 3); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); /* priority */ if (sscanf(str, "%u", &cand->priority) != 1) ABORT(R_BAD_DATA); if (cand->priority < 1) ABORT(R_BAD_DATA); skip_to_past_space(&str); if (*str == '\0') ABORT(R_BAD_DATA); /* Peer address/port */ if ((r=grab_token(&str, &connection_address))) ABORT(r); if (*str == '\0') ABORT(R_BAD_DATA); addr = inet_addr(connection_address); if (addr == INADDR_NONE) ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if (sscanf(str, "%u", &port) != 1) ABORT(R_BAD_DATA); if (port < 1 || port > 0x0FFFF) ABORT(R_BAD_DATA); /* Assume v4 for now */ if(r=nr_ip4_port_to_transport_addr(ntohl(addr),port,IPPROTO_UDP,&cand->addr)) ABORT(r); skip_to_past_space(&str); if (*str == '\0') ABORT(R_BAD_DATA); /* Type */ if (strncasecmp("typ", str, 3)) ABORT(R_BAD_DATA); fast_forward(&str, 3); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); assert(nr_ice_candidate_type_names[0] == 0); for (i = 1; nr_ice_candidate_type_names[i]; ++i) { if(!strncasecmp(nr_ice_candidate_type_names[i], str, strlen(nr_ice_candidate_type_names[i]))) { cand->type=i; break; } } if (nr_ice_candidate_type_names[i] == 0) ABORT(R_BAD_DATA); fast_forward(&str, strlen(nr_ice_candidate_type_names[i])); /* Look for the other side's raddr, rport */ /* raddr, rport */ switch (cand->type) { case HOST: break; case SERVER_REFLEXIVE: case PEER_REFLEXIVE: case RELAYED: skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if (strncasecmp("raddr", str, 5)) ABORT(R_BAD_DATA); fast_forward(&str, 5); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if ((r=grab_token(&str, &rel_addr))) ABORT(r); if (*str == '\0') ABORT(R_BAD_DATA); addr = inet_addr(rel_addr); if (addr == INADDR_NONE) ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if (strncasecmp("rport", str, 5)) ABORT(R_BAD_DATA); fast_forward(&str, 5); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if (sscanf(str, "%u", &port) != 1) ABORT(R_BAD_DATA); if (port < 1 || port > 0x0FFFF) ABORT(R_BAD_DATA); /* Assume v4 for now */ if(r=nr_ip4_port_to_transport_addr(ntohl(addr),port,IPPROTO_UDP,&cand->base)) ABORT(r); skip_to_past_space(&str); /* it's expected to be at EOD at this point */ break; default: ABORT(R_INTERNAL); break; } skip_whitespace(&str); assert(strlen(str) == 0); *candp=cand; _status=0; abort: if (_status) r_log(LOG_ICE,LOG_WARNING,"ICE(%s): Error parsing attribute: %s",ctx->label,orig); RFREE(connection_address); RFREE(rel_addr); return(_status); }