Exemple #1
0
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);
}