LCOV - code coverage report
Current view: top level - media/mtransport/third_party/nICEr/src/ice - ice_parser.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 300 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             : Copyright (c) 2007, Adobe Systems, Incorporated
       3             : All rights reserved.
       4             : 
       5             : Redistribution and use in source and binary forms, with or without
       6             : modification, are permitted provided that the following conditions are
       7             : met:
       8             : 
       9             : * Redistributions of source code must retain the above copyright
      10             :   notice, this list of conditions and the following disclaimer.
      11             : 
      12             : * Redistributions in binary form must reproduce the above copyright
      13             :   notice, this list of conditions and the following disclaimer in the
      14             :   documentation and/or other materials provided with the distribution.
      15             : 
      16             : * Neither the name of Adobe Systems, Network Resonance nor the names of its
      17             :   contributors may be used to endorse or promote products derived from
      18             :   this software without specific prior written permission.
      19             : 
      20             : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      21             : "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      22             : LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      23             : A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      24             : OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      25             : SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      26             : LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      27             : DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      28             : THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      29             : (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      30             : OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      31             : */
      32             : 
      33             : 
      34             : 
      35             : static char *RCSSTRING __UNUSED__="$Id: ice_parser.c,v 1.2 2008/04/28 17:59:01 ekr Exp $";
      36             : 
      37             : #include <csi_platform.h>
      38             : #include <sys/types.h>
      39             : #ifdef WIN32
      40             : #include <winsock2.h>
      41             : #else
      42             : #include <sys/socket.h>
      43             : #include <netinet/in.h>
      44             : #include <arpa/inet.h>
      45             : #include <strings.h>
      46             : #endif
      47             : #include <string.h>
      48             : #include <assert.h>
      49             : #include <ctype.h>
      50             : #include "nr_api.h"
      51             : #include "ice_ctx.h"
      52             : #include "ice_candidate.h"
      53             : #include "ice_reg.h"
      54             : 
      55             : static void
      56           0 : skip_whitespace(char **str)
      57             : {
      58           0 :     char *c = *str;
      59           0 :     while (*c == ' ')
      60           0 :         ++c;
      61             : 
      62           0 :     *str = c;
      63           0 : }
      64             : 
      65             : static void
      66           0 : fast_forward(char **str, int skip)
      67             : {
      68           0 :     char *c = *str;
      69           0 :     while (*c != '\0' && skip-- > 0)
      70           0 :         ++c;
      71             : 
      72           0 :     *str = c;
      73           0 : }
      74             : 
      75             : static void
      76           0 : skip_to_past_space(char **str)
      77             : {
      78           0 :     char *c = *str;
      79           0 :     while (*c != ' ' && *c != '\0')
      80           0 :         ++c;
      81             : 
      82           0 :     *str = c;
      83             : 
      84           0 :     skip_whitespace(str);
      85           0 : }
      86             : 
      87             : static int
      88           0 : grab_token(char **str, char **out)
      89             : {
      90             :     int _status;
      91           0 :     char *c = *str;
      92             :     int len;
      93             :     char *tmp;
      94             : 
      95           0 :     while (*c != ' ' && *c != '\0')
      96           0 :         ++c;
      97             : 
      98           0 :     len = c - *str;
      99             : 
     100           0 :     tmp = RMALLOC(len + 1);
     101           0 :     if (!tmp)
     102           0 :         ABORT(R_NO_MEMORY);
     103             : 
     104           0 :     memcpy(tmp, *str, len);
     105           0 :     tmp[len] = '\0';
     106             : 
     107           0 :     *str = c;
     108           0 :     *out = tmp;
     109             : 
     110           0 :     _status = 0;
     111             : abort:
     112           0 :     return _status;
     113             : }
     114             : 
     115             : int
     116           0 : nr_ice_peer_candidate_from_attribute(nr_ice_ctx *ctx,char *orig,nr_ice_media_stream *stream,nr_ice_candidate **candp)
     117             : {
     118             :     int r,_status;
     119           0 :     char* str = orig;
     120             :     nr_ice_candidate *cand;
     121           0 :     char *connection_address=0;
     122             :     unsigned int port;
     123             :     int i;
     124             :     unsigned int component_id;
     125           0 :     char *rel_addr=0;
     126             :     unsigned char transport;
     127             : 
     128           0 :     if(!(cand=RCALLOC(sizeof(nr_ice_candidate))))
     129           0 :         ABORT(R_NO_MEMORY);
     130             : 
     131           0 :     if(!(cand->label=r_strdup(orig)))
     132           0 :         ABORT(R_NO_MEMORY);
     133             : 
     134           0 :     cand->ctx=ctx;
     135           0 :     cand->isock=0;
     136           0 :     cand->state=NR_ICE_CAND_PEER_CANDIDATE_UNPAIRED;
     137           0 :     cand->stream=stream;
     138           0 :     skip_whitespace(&str);
     139             : 
     140             :     /* Skip a= if present */
     141           0 :     if (!strncmp(str, "a=", 2))
     142           0 :         str += 2;
     143             : 
     144             :     /* Candidate attr */
     145           0 :     if (strncasecmp(str, "candidate:", 10))
     146           0 :         ABORT(R_BAD_DATA);
     147             : 
     148           0 :     fast_forward(&str, 10);
     149           0 :     if (*str == '\0')
     150           0 :         ABORT(R_BAD_DATA);
     151             : 
     152           0 :     skip_whitespace(&str);
     153           0 :     if (*str == '\0')
     154           0 :         ABORT(R_BAD_DATA);
     155             : 
     156             :     /* Foundation */
     157           0 :     if ((r=grab_token(&str, &cand->foundation)))
     158           0 :         ABORT(r);
     159             : 
     160           0 :     if (*str == '\0')
     161           0 :         ABORT(R_BAD_DATA);
     162             : 
     163           0 :     skip_whitespace(&str);
     164           0 :     if (*str == '\0')
     165           0 :         ABORT(R_BAD_DATA);
     166             : 
     167             :     /* component */
     168           0 :     if (sscanf(str, "%u", &component_id) != 1)
     169           0 :         ABORT(R_BAD_DATA);
     170             : 
     171           0 :     if (component_id < 1 || component_id > 256)
     172           0 :         ABORT(R_BAD_DATA);
     173             : 
     174           0 :     cand->component_id = (UCHAR)component_id;
     175             : 
     176           0 :     skip_to_past_space(&str);
     177           0 :     if (*str == '\0')
     178           0 :         ABORT(R_BAD_DATA);
     179             : 
     180             :     /* Protocol */
     181           0 :     if (!strncasecmp(str, "UDP", 3))
     182           0 :       transport=IPPROTO_UDP;
     183           0 :     else if (!strncasecmp(str, "TCP", 3))
     184           0 :       transport=IPPROTO_TCP;
     185             :     else
     186           0 :       ABORT(R_BAD_DATA);
     187             : 
     188           0 :     fast_forward(&str, 3);
     189           0 :     if (*str == '\0')
     190           0 :         ABORT(R_BAD_DATA);
     191             : 
     192           0 :     skip_whitespace(&str);
     193           0 :     if (*str == '\0')
     194           0 :         ABORT(R_BAD_DATA);
     195             : 
     196             :     /* priority */
     197           0 :     if (sscanf(str, "%u", &cand->priority) != 1)
     198           0 :         ABORT(R_BAD_DATA);
     199             : 
     200           0 :     if (cand->priority < 1)
     201           0 :         ABORT(R_BAD_DATA);
     202             : 
     203           0 :     skip_to_past_space(&str);
     204           0 :     if (*str == '\0')
     205           0 :         ABORT(R_BAD_DATA);
     206             : 
     207             :     /* Peer address/port */
     208           0 :     if ((r=grab_token(&str, &connection_address)))
     209           0 :         ABORT(r);
     210             : 
     211           0 :     if (*str == '\0')
     212           0 :         ABORT(R_BAD_DATA);
     213             : 
     214           0 :     skip_whitespace(&str);
     215           0 :     if (*str == '\0')
     216           0 :         ABORT(R_BAD_DATA);
     217             : 
     218           0 :     if (sscanf(str, "%u", &port) != 1)
     219           0 :         ABORT(R_BAD_DATA);
     220             : 
     221           0 :     if (port < 1 || port > 0x0FFFF)
     222           0 :         ABORT(R_BAD_DATA);
     223             : 
     224           0 :     if ((r=nr_str_port_to_transport_addr(connection_address,port,transport,&cand->addr)))
     225           0 :       ABORT(r);
     226             : 
     227           0 :     skip_to_past_space(&str);
     228           0 :     if (*str == '\0')
     229           0 :         ABORT(R_BAD_DATA);
     230             : 
     231             :     /* Type */
     232           0 :     if (strncasecmp("typ", str, 3))
     233           0 :         ABORT(R_BAD_DATA);
     234             : 
     235           0 :     fast_forward(&str, 3);
     236           0 :     if (*str == '\0')
     237           0 :         ABORT(R_BAD_DATA);
     238             : 
     239           0 :     skip_whitespace(&str);
     240           0 :     if (*str == '\0')
     241           0 :         ABORT(R_BAD_DATA);
     242             : 
     243           0 :     assert(nr_ice_candidate_type_names[0] == 0);
     244             : 
     245           0 :     for (i = 1; nr_ice_candidate_type_names[i]; ++i) {
     246           0 :         if(!strncasecmp(nr_ice_candidate_type_names[i], str, strlen(nr_ice_candidate_type_names[i]))) {
     247           0 :             cand->type=i;
     248           0 :             break;
     249             :         }
     250             :     }
     251           0 :     if (nr_ice_candidate_type_names[i] == 0)
     252           0 :         ABORT(R_BAD_DATA);
     253             : 
     254           0 :     fast_forward(&str, strlen(nr_ice_candidate_type_names[i]));
     255             : 
     256             :     /* Look for the other side's raddr, rport */
     257             :     /* raddr, rport */
     258           0 :     switch (cand->type) {
     259             :     case HOST:
     260           0 :         break;
     261             :     case SERVER_REFLEXIVE:
     262             :     case PEER_REFLEXIVE:
     263             :     case RELAYED:
     264             : 
     265           0 :         skip_whitespace(&str);
     266           0 :         if (*str == '\0')
     267           0 :             ABORT(R_BAD_DATA);
     268             : 
     269           0 :         if (strncasecmp("raddr", str, 5))
     270           0 :             ABORT(R_BAD_DATA);
     271             : 
     272           0 :         fast_forward(&str, 5);
     273           0 :         if (*str == '\0')
     274           0 :             ABORT(R_BAD_DATA);
     275             : 
     276           0 :         skip_whitespace(&str);
     277           0 :         if (*str == '\0')
     278           0 :             ABORT(R_BAD_DATA);
     279             : 
     280           0 :         if ((r=grab_token(&str, &rel_addr)))
     281           0 :             ABORT(r);
     282             : 
     283           0 :         if (*str == '\0')
     284           0 :             ABORT(R_BAD_DATA);
     285             : 
     286           0 :         skip_whitespace(&str);
     287           0 :         if (*str == '\0')
     288           0 :             ABORT(R_BAD_DATA);
     289             : 
     290           0 :         if (strncasecmp("rport", str, 5))
     291           0 :               ABORT(R_BAD_DATA);
     292             : 
     293           0 :         fast_forward(&str, 5);
     294           0 :         if (*str == '\0')
     295           0 :             ABORT(R_BAD_DATA);
     296             : 
     297           0 :         skip_whitespace(&str);
     298           0 :         if (*str == '\0')
     299           0 :             ABORT(R_BAD_DATA);
     300             : 
     301           0 :         if (sscanf(str, "%u", &port) != 1)
     302           0 :             ABORT(R_BAD_DATA);
     303             : 
     304           0 :         if (port > 0x0FFFF)
     305           0 :             ABORT(R_BAD_DATA);
     306             : 
     307           0 :         if ((r=nr_str_port_to_transport_addr(rel_addr,port,transport,&cand->base)))
     308           0 :           ABORT(r);
     309             : 
     310           0 :         skip_to_past_space(&str);
     311             :         /* it's expected to be at EOD at this point */
     312             : 
     313           0 :         break;
     314             :     default:
     315           0 :         ABORT(R_INTERNAL);
     316             :         break;
     317             :     }
     318             : 
     319           0 :     skip_whitespace(&str);
     320             : 
     321           0 :     if (transport == IPPROTO_TCP && cand->type != RELAYED) {
     322             :       /* Parse tcptype extension per RFC 6544 S 4.5 */
     323           0 :       if (strncasecmp("tcptype ", str, 8))
     324           0 :         ABORT(R_BAD_DATA);
     325             : 
     326           0 :       fast_forward(&str, 8);
     327           0 :       skip_whitespace(&str);
     328             : 
     329           0 :       for (i = 1; nr_ice_candidate_tcp_type_names[i]; ++i) {
     330           0 :         if(!strncasecmp(nr_ice_candidate_tcp_type_names[i], str, strlen(nr_ice_candidate_tcp_type_names[i]))) {
     331           0 :           cand->tcp_type=i;
     332           0 :           fast_forward(&str, strlen(nr_ice_candidate_tcp_type_names[i]));
     333           0 :           break;
     334             :         }
     335             :       }
     336             : 
     337           0 :       if (cand->tcp_type == 0)
     338           0 :         ABORT(R_BAD_DATA);
     339             : 
     340           0 :       if (*str && *str != ' ')
     341           0 :         ABORT(R_BAD_DATA);
     342             :     }
     343             :     /* Ignore extensions per RFC 5245 S 15.1 */
     344             : #if 0
     345             :     /* This used to be an assert, but we don't want to exit on invalid
     346             :        remote data */
     347             :     if (strlen(str) != 0) {
     348             :       ABORT(R_BAD_DATA);
     349             :     }
     350             : #endif
     351             : 
     352           0 :     nr_ice_candidate_compute_codeword(cand);
     353             : 
     354           0 :     *candp=cand;
     355             : 
     356           0 :     _status=0;
     357             :   abort:
     358           0 :     if (_status){
     359           0 :         r_log(LOG_ICE,LOG_WARNING,"ICE(%s): Error parsing attribute: %s",ctx->label,orig);
     360           0 :         nr_ice_candidate_destroy(&cand);
     361             :     }
     362             : 
     363           0 :     RFREE(connection_address);
     364           0 :     RFREE(rel_addr);
     365           0 :     return(_status);
     366             : }
     367             : 
     368             : 
     369             : int
     370           0 : nr_ice_peer_ctx_parse_media_stream_attribute(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *attr)
     371             : {
     372             :     int r,_status;
     373           0 :     char *orig = 0;
     374             :     char *str;
     375             : 
     376           0 :     orig = str = attr;
     377             : 
     378           0 :     if (!strncasecmp(str, "ice-ufrag:", 10)) {
     379           0 :       fast_forward(&str, 10);
     380           0 :       if (*str == '\0')
     381           0 :         ABORT(R_BAD_DATA);
     382             : 
     383           0 :       skip_whitespace(&str);
     384           0 :       if (*str == '\0')
     385           0 :         ABORT(R_BAD_DATA);
     386             : 
     387           0 :       if ((r=grab_token(&str, &stream->ufrag)))
     388           0 :         ABORT(r);
     389             :     }
     390           0 :     else if (!strncasecmp(str, "ice-pwd:", 8)) {
     391           0 :       fast_forward(&str, 8);
     392           0 :       if (*str == '\0')
     393           0 :         ABORT(R_BAD_DATA);
     394             : 
     395           0 :       skip_whitespace(&str);
     396           0 :       if (*str == '\0')
     397           0 :         ABORT(R_BAD_DATA);
     398             : 
     399           0 :       if ((r=grab_token(&str, &stream->pwd)))
     400           0 :         ABORT(r);
     401             :     }
     402             :     else {
     403           0 :       ABORT(R_BAD_DATA);
     404             :     }
     405             : 
     406           0 :     skip_whitespace(&str);
     407             : 
     408             :     /* RFC 5245 grammar doesn't have an extension point for ice-pwd or
     409             :        ice-ufrag: if there's anything left on the line, we treat it as bad. */
     410           0 :     if (str[0] != '\0') {
     411           0 :       ABORT(R_BAD_DATA);
     412             :     }
     413             : 
     414           0 :     _status=0;
     415             :   abort:
     416           0 :     if (_status) {
     417           0 :       if (orig)
     418           0 :         r_log(LOG_ICE,LOG_WARNING,"ICE-PEER(%s): Error parsing attribute: %s",pctx->label,orig);
     419             :     }
     420             : 
     421           0 :     return(_status);
     422             : }
     423             : 
     424             : int
     425           0 : nr_ice_peer_ctx_parse_global_attributes(nr_ice_peer_ctx *pctx, char **attrs, int attr_ct)
     426             : {
     427             :     int r,_status;
     428             :     int i;
     429           0 :     char *orig = 0;
     430             :     char *str;
     431           0 :     char *component_id = 0;
     432           0 :     char *connection_address = 0;
     433             :     unsigned int port;
     434             :     in_addr_t addr;
     435           0 :     char *ice_option_tag = 0;
     436             : 
     437           0 :     for(i=0;i<attr_ct;i++){
     438           0 :         orig = str = attrs[i];
     439             : 
     440           0 :         component_id = 0;
     441           0 :         connection_address = 0;
     442           0 :         ice_option_tag = 0;
     443             : 
     444           0 :         if (!strncasecmp(str, "remote-candidates:", 18)) {
     445           0 :             fast_forward(&str, 18);
     446           0 :             skip_whitespace(&str);
     447             : 
     448           0 :             while (*str != '\0') {
     449           0 :                 if ((r=grab_token(&str, &component_id)))
     450           0 :                     ABORT(r);
     451             : 
     452           0 :                 if (*str == '\0')
     453           0 :                     ABORT(R_BAD_DATA);
     454             : 
     455           0 :                 skip_whitespace(&str);
     456           0 :                 if (*str == '\0')
     457           0 :                     ABORT(R_BAD_DATA);
     458             : 
     459           0 :                 if ((r=grab_token(&str, &connection_address)))
     460           0 :                     ABORT(r);
     461             : 
     462           0 :                 if (*str == '\0')
     463           0 :                     ABORT(R_BAD_DATA);
     464             : 
     465           0 :                 addr = inet_addr(connection_address);
     466           0 :                 if (addr == INADDR_NONE)
     467           0 :                     ABORT(R_BAD_DATA);
     468             : 
     469           0 :                 skip_whitespace(&str);
     470           0 :                 if (*str == '\0')
     471           0 :                     ABORT(R_BAD_DATA);
     472             : 
     473           0 :                 if (sscanf(str, "%u", &port) != 1)
     474           0 :                     ABORT(R_BAD_DATA);
     475             : 
     476           0 :                 if (port < 1 || port > 0x0FFFF)
     477           0 :                     ABORT(R_BAD_DATA);
     478             : 
     479           0 :                 skip_to_past_space(&str);
     480             : 
     481             : #if 0
     482             :                 /* TODO: !nn! just drop on the floor for now, later put somewhere */
     483             :                 /* Assume v4 for now */
     484             :                 if(r=nr_ip4_port_to_transport_addr(ntohl(addr),port,IPPROTO_UDP,&candidate->base))
     485             :                   ABORT(r);
     486             : 
     487             :                 TAILQ_INSERT_TAIL(head, elm, field);
     488             : #endif
     489             : 
     490           0 :                 component_id = 0;  /* prevent free */
     491           0 :                 RFREE(connection_address);
     492           0 :                 connection_address = 0;  /* prevent free */
     493             :             }
     494             :         }
     495           0 :         else if (!strncasecmp(str, "ice-lite", 8)) {
     496           0 :             pctx->peer_lite = 1;
     497             : 
     498           0 :             fast_forward(&str, 8);
     499             :         }
     500           0 :         else if (!strncasecmp(str, "ice-mismatch", 12)) {
     501           0 :             pctx->peer_ice_mismatch = 1;
     502             : 
     503           0 :             fast_forward(&str, 12);
     504             :         }
     505           0 :         else if (!strncasecmp(str, "ice-ufrag:", 10)) {
     506           0 :             fast_forward(&str, 10);
     507           0 :             if (*str == '\0')
     508           0 :                 ABORT(R_BAD_DATA);
     509             : 
     510           0 :             skip_whitespace(&str);
     511           0 :             if (*str == '\0')
     512           0 :                 ABORT(R_BAD_DATA);
     513             : 
     514           0 :             RFREE(pctx->peer_ufrag);
     515           0 :             pctx->peer_ufrag = 0;
     516           0 :             if ((r=grab_token(&str, &pctx->peer_ufrag)))
     517           0 :                 ABORT(r);
     518             :         }
     519           0 :         else if (!strncasecmp(str, "ice-pwd:", 8)) {
     520           0 :             fast_forward(&str, 8);
     521           0 :             if (*str == '\0')
     522           0 :                 ABORT(R_BAD_DATA);
     523             : 
     524           0 :             skip_whitespace(&str);
     525           0 :             if (*str == '\0')
     526           0 :                 ABORT(R_BAD_DATA);
     527             : 
     528           0 :             RFREE(pctx->peer_pwd);
     529           0 :             pctx->peer_pwd = 0;
     530           0 :             if ((r=grab_token(&str, &pctx->peer_pwd)))
     531           0 :                 ABORT(r);
     532             :         }
     533           0 :         else if (!strncasecmp(str, "ice-options:", 12)) {
     534           0 :             fast_forward(&str, 12);
     535           0 :             skip_whitespace(&str);
     536             : 
     537           0 :             while (*str != '\0') {
     538           0 :                 if ((r=grab_token(&str, &ice_option_tag)))
     539           0 :                     ABORT(r);
     540             : 
     541           0 :                 skip_whitespace(&str);
     542             : 
     543             :                 //TODO: for now, just throw away; later put somewhere
     544           0 :                 RFREE(ice_option_tag);
     545             : 
     546           0 :                 ice_option_tag = 0;  /* prevent free */
     547             :             }
     548             :         }
     549             :         else {
     550           0 :             ABORT(R_BAD_DATA);
     551             :         }
     552             : 
     553           0 :         skip_whitespace(&str);
     554             : 
     555             :       /* RFC 5245 grammar doesn't have an extension point for any of the
     556             :          preceding attributes: if there's anything left on the line, we
     557             :          treat it as bad data. */
     558           0 :       if (str[0] != '\0') {
     559           0 :         ABORT(R_BAD_DATA);
     560             :       }
     561             :     }
     562             : 
     563           0 :     _status=0;
     564             :   abort:
     565           0 :     if (_status) {
     566           0 :       if (orig)
     567           0 :         r_log(LOG_ICE,LOG_WARNING,"ICE-PEER(%s): Error parsing attribute: %s",pctx->label,orig);
     568             :     }
     569             : 
     570           0 :     RFREE(connection_address);
     571           0 :     RFREE(component_id);
     572           0 :     RFREE(ice_option_tag);
     573           0 :     return(_status);
     574             : }
     575             : 

Generated by: LCOV version 1.13