LCOV - code coverage report
Current view: top level - media/mtransport/third_party/nICEr/src/ice - ice_socket.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 157 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 8 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_socket.c,v 1.2 2008/04/28 17:59:01 ekr Exp $";
      36             : 
      37             : #include <assert.h>
      38             : #include <string.h>
      39             : #include "nr_api.h"
      40             : #include "ice_ctx.h"
      41             : #include "stun.h"
      42             : #include "nr_socket_buffered_stun.h"
      43             : #include "nr_socket_multi_tcp.h"
      44             : 
      45           0 : static void nr_ice_socket_readable_cb(NR_SOCKET s, int how, void *cb_arg)
      46             :   {
      47             :     int r;
      48             :     nr_ice_stun_ctx *sc1,*sc2;
      49           0 :     nr_ice_socket *sock=cb_arg;
      50             :     UCHAR buf[9216];
      51             :     char string[256];
      52             :     nr_transport_addr addr;
      53             :     int len;
      54             :     size_t len_s;
      55             :     int is_stun;
      56             :     int is_req;
      57             :     int is_ind;
      58           0 :     int processed_indication=0;
      59             : 
      60           0 :     nr_socket *stun_srv_sock=sock->sock;
      61             : 
      62           0 :     r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Socket ready to read",sock->ctx->label);
      63             : 
      64             :     /* Re-arm first! */
      65           0 :     if (sock->type != NR_ICE_SOCKET_TYPE_STREAM_TCP) {
      66           0 :       r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): rearming",sock->ctx->label);
      67           0 :       NR_ASYNC_WAIT(s,how,nr_ice_socket_readable_cb,cb_arg);
      68             :     }
      69             : 
      70           0 :     if(r=nr_socket_recvfrom(sock->sock,buf,sizeof(buf),&len_s,0,&addr)){
      71           0 :       if (r != R_WOULDBLOCK && (sock->type != NR_ICE_SOCKET_TYPE_DGRAM)) {
      72             :         /* Report this error upward. Bug 946423 */
      73           0 :         r_log(LOG_ICE,LOG_ERR,"ICE(%s): Error %d on reliable socket(%p). Abandoning.",sock->ctx->label, r, s);
      74             :       }
      75           0 :       return;
      76             :     }
      77             : 
      78             :     /* Deal with the fact that sizeof(int) and sizeof(size_t) may not
      79             :        be the same */
      80           0 :     if (len_s > (size_t)INT_MAX)
      81           0 :       return;
      82             : 
      83           0 :     len = (int)len_s;
      84             : 
      85             : #ifdef USE_TURN
      86             :   re_process:
      87             : #endif /* USE_TURN */
      88           0 :     r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Read %d bytes %sfrom %s",sock->ctx->label,len,(processed_indication ? "relayed " : ""),addr.as_string);
      89             : 
      90             :     /* First question: is this STUN or not? */
      91           0 :     is_stun=nr_is_stun_message(buf,len);
      92             : 
      93           0 :     if(is_stun){
      94           0 :       is_req=nr_is_stun_request_message(buf,len);
      95           0 :       is_ind=is_req?0:nr_is_stun_indication_message(buf,len);
      96             : 
      97           0 :       snprintf(string, sizeof(string)-1, "ICE(%s): Message is STUN (%s)",sock->ctx->label,
      98           0 :                is_req ? "request" : (is_ind ? "indication" : "other"));
      99           0 :       r_dump(NR_LOG_STUN, LOG_DEBUG, string, (char*)buf, len);
     100             : 
     101             : 
     102             :       /* We need to offer it to all of our stun contexts
     103             :          to see who bites */
     104           0 :       sc1=TAILQ_FIRST(&sock->stun_ctxs);
     105           0 :       while(sc1){
     106           0 :         sc2=TAILQ_NEXT(sc1,entry);
     107             : 
     108           0 :         r=-1;
     109           0 :         switch(sc1->type){
     110             :           /* This has been deleted, prune... */
     111             :           case NR_ICE_STUN_NONE:
     112           0 :             TAILQ_REMOVE(&sock->stun_ctxs,sc1,entry);
     113           0 :             RFREE(sc1);
     114           0 :             break;
     115             : 
     116             :           case NR_ICE_STUN_CLIENT:
     117           0 :             if(!(is_req||is_ind)){
     118           0 :                 r=nr_stun_client_process_response(sc1->u.client,buf,len,&addr);
     119             :             }
     120           0 :             break;
     121             : 
     122             :           case NR_ICE_STUN_SERVER:
     123           0 :             if(is_req){
     124           0 :               r=nr_stun_server_process_request(sc1->u.server,stun_srv_sock,(char *)buf,len,&addr,NR_STUN_AUTH_RULE_SHORT_TERM);
     125             :             }
     126           0 :             break;
     127             : #ifdef USE_TURN
     128             :           case NR_ICE_TURN_CLIENT:
     129             :             /* data indications are ok, so don't ignore those */
     130             :             /* Check that this is from the right TURN server address. Else
     131             :                skip */
     132           0 :             if (nr_transport_addr_cmp(
     133           0 :                     &sc1->u.turn_client.turn_client->turn_server_addr,
     134             :                     &addr, NR_TRANSPORT_ADDR_CMP_MODE_ALL))
     135           0 :               break;
     136             : 
     137           0 :             if(!is_req){
     138           0 :               if(!is_ind)
     139           0 :                 r=nr_turn_client_process_response(sc1->u.turn_client.turn_client,buf,len,&addr);
     140             :               else{
     141             :                 nr_transport_addr n_addr;
     142             :                 size_t n_len;
     143             : 
     144           0 :                 if (processed_indication) {
     145             :                   /* Don't allow recursively wrapped indications */
     146           0 :                   r_log(LOG_ICE, LOG_WARNING,
     147             :                         "ICE(%s): discarding recursively wrapped indication",
     148           0 :                         sock->ctx->label);
     149           0 :                   break;
     150             :                 }
     151             :                 /* This is a bit of a hack. If it's a data indication, strip
     152             :                    off the TURN framing and re-enter. This works because
     153             :                    all STUN processing is on the same physical socket.
     154             :                    We don't care about other kinds of indication */
     155           0 :                 r=nr_turn_client_parse_data_indication(
     156             :                     sc1->u.turn_client.turn_client, &addr,
     157             :                     buf, len, buf, &n_len, len, &n_addr);
     158           0 :                 if(!r){
     159           0 :                   r_log(LOG_ICE,LOG_DEBUG,"Unwrapped a data indication.");
     160           0 :                   len=n_len;
     161           0 :                   nr_transport_addr_copy(&addr,&n_addr);
     162           0 :                   stun_srv_sock=sc1->u.turn_client.turn_sock;
     163           0 :                   processed_indication=1;
     164           0 :                   goto re_process;
     165             :                 }
     166             :               }
     167             :             }
     168           0 :             break;
     169             : #endif /* USE_TURN */
     170             : 
     171             :           default:
     172           0 :             assert(0); /* Can't happen */
     173             :             return;
     174             :         }
     175           0 :         if(!r) {
     176           0 :           break;
     177             :         }
     178             : 
     179           0 :         sc1=sc2;
     180             :       }
     181           0 :       if(!sc1){
     182           0 :         if (nr_ice_ctx_is_known_id(sock->ctx,((nr_stun_message_header*)buf)->id.octet))
     183           0 :             r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Message is a retransmit",sock->ctx->label);
     184             :         else
     185           0 :             r_log(LOG_ICE,LOG_NOTICE,"ICE(%s): Message does not correspond to any registered stun ctx",sock->ctx->label);
     186             :       }
     187             :     }
     188             :     else{
     189           0 :       r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Message is not STUN",sock->ctx->label);
     190             : 
     191           0 :       nr_ice_ctx_deliver_packet(sock->ctx, sock->component, &addr, buf, len);
     192             :     }
     193             : 
     194           0 :     return;
     195             :   }
     196             : 
     197           0 : int nr_ice_socket_create(nr_ice_ctx *ctx,nr_ice_component *comp, nr_socket *nsock, int type, nr_ice_socket **sockp)
     198             :   {
     199           0 :     nr_ice_socket *sock=0;
     200             :     NR_SOCKET fd;
     201             :     nr_transport_addr addr;
     202             :     int r,_status;
     203             : 
     204           0 :     if(!(sock=RCALLOC(sizeof(nr_ice_socket))))
     205           0 :       ABORT(R_NO_MEMORY);
     206             : 
     207           0 :     sock->sock=nsock;
     208           0 :     sock->ctx=ctx;
     209           0 :     sock->component=comp;
     210             : 
     211           0 :     if(r=nr_socket_getaddr(nsock, &addr))
     212           0 :       ABORT(r);
     213             : 
     214           0 :     if (type == NR_ICE_SOCKET_TYPE_DGRAM) {
     215           0 :       assert(addr.protocol == IPPROTO_UDP);
     216             :     }
     217             :     else {
     218           0 :       assert(addr.protocol == IPPROTO_TCP);
     219             :     }
     220           0 :     sock->type=type;
     221             : 
     222           0 :     TAILQ_INIT(&sock->candidates);
     223           0 :     TAILQ_INIT(&sock->stun_ctxs);
     224             : 
     225           0 :     if (sock->type == NR_ICE_SOCKET_TYPE_DGRAM){
     226           0 :       if((r=nr_socket_getfd(nsock,&fd)))
     227           0 :         ABORT(r);
     228           0 :       NR_ASYNC_WAIT(fd,NR_ASYNC_WAIT_READ,nr_ice_socket_readable_cb,sock);
     229             :     }
     230           0 :     else if (sock->type == NR_ICE_SOCKET_TYPE_STREAM_TURN) {
     231             :       /* some OS's (e.g. Linux) don't like to see un-connected TCP sockets in
     232             :        * the poll socket set. */
     233           0 :       nr_socket_buffered_stun_set_readable_cb(nsock,nr_ice_socket_readable_cb,sock);
     234             :     }
     235           0 :     else if (sock->type == NR_ICE_SOCKET_TYPE_STREAM_TCP) {
     236             :       /* in this case we can't hook up using NR_ASYNC_WAIT, because nr_socket_multi_tcp
     237             :          consists of multiple nr_sockets and file descriptors. */
     238           0 :       if((r=nr_socket_multi_tcp_set_readable_cb(nsock,nr_ice_socket_readable_cb,sock)))
     239           0 :         ABORT(r);
     240             :     }
     241             : 
     242           0 :     *sockp=sock;
     243             : 
     244           0 :     _status=0;
     245             :   abort:
     246           0 :     if(_status) RFREE(sock);
     247           0 :     return(_status);
     248             :   }
     249             : 
     250             : 
     251           0 : int nr_ice_socket_destroy(nr_ice_socket **isockp)
     252             :   {
     253             :     nr_ice_stun_ctx *s1,*s2;
     254             :     nr_ice_socket *isock;
     255             : 
     256           0 :     if(!isockp || !*isockp)
     257           0 :       return(0);
     258             : 
     259           0 :     isock=*isockp;
     260           0 :     *isockp=0;
     261             : 
     262             :     /* Close the socket */
     263           0 :     nr_ice_socket_close(isock);
     264             : 
     265             :     /* The STUN server */
     266           0 :     nr_stun_server_ctx_destroy(&isock->stun_server);
     267             : 
     268             :     /* Now clean up the STUN ctxs */
     269           0 :     TAILQ_FOREACH_SAFE(s1, &isock->stun_ctxs, entry, s2){
     270           0 :       TAILQ_REMOVE(&isock->stun_ctxs, s1, entry);
     271           0 :       RFREE(s1);
     272             :     }
     273             : 
     274           0 :     RFREE(isock);
     275             : 
     276           0 :     return(0);
     277             :   }
     278             : 
     279           0 : int nr_ice_socket_close(nr_ice_socket *isock)
     280             :   {
     281             : #ifdef NR_SOCKET_IS_VOID_PTR
     282           0 :     NR_SOCKET fd=NULL;
     283           0 :     NR_SOCKET no_socket = NULL;
     284             : #else
     285             :     NR_SOCKET fd=-1;
     286             :     NR_SOCKET no_socket = -1;
     287             : #endif
     288             : 
     289           0 :     if (!isock||!isock->sock)
     290           0 :       return(0);
     291             : 
     292           0 :     if (isock->type != NR_ICE_SOCKET_TYPE_STREAM_TCP){
     293           0 :       nr_socket_getfd(isock->sock,&fd);
     294           0 :       assert(isock->sock!=0);
     295           0 :       if(fd != no_socket){
     296           0 :         NR_ASYNC_CANCEL(fd,NR_ASYNC_WAIT_READ);
     297           0 :         NR_ASYNC_CANCEL(fd,NR_ASYNC_WAIT_WRITE);
     298             :       }
     299             :     }
     300           0 :     nr_socket_destroy(&isock->sock);
     301             : 
     302           0 :     return(0);
     303             :   }
     304             : 
     305           0 : int nr_ice_socket_register_stun_client(nr_ice_socket *sock, nr_stun_client_ctx *srv,void **handle)
     306             :   {
     307           0 :     nr_ice_stun_ctx *sc=0;
     308             :     int _status;
     309             : 
     310           0 :     if(!(sc=RCALLOC(sizeof(nr_ice_stun_ctx))))
     311           0 :       ABORT(R_NO_MEMORY);
     312             : 
     313           0 :     sc->type=NR_ICE_STUN_CLIENT;
     314           0 :     sc->u.client=srv;
     315             : 
     316           0 :     TAILQ_INSERT_TAIL(&sock->stun_ctxs,sc,entry);
     317             : 
     318           0 :     *handle=sc;
     319             : 
     320           0 :     _status=0;
     321             :   abort:
     322           0 :     return(_status);
     323             :   }
     324             : 
     325           0 : int nr_ice_socket_register_stun_server(nr_ice_socket *sock, nr_stun_server_ctx *srv,void **handle)
     326             :   {
     327           0 :     nr_ice_stun_ctx *sc=0;
     328             :     int _status;
     329             : 
     330           0 :     if(!(sc=RCALLOC(sizeof(nr_ice_stun_ctx))))
     331           0 :       ABORT(R_NO_MEMORY);
     332             : 
     333           0 :     sc->type=NR_ICE_STUN_SERVER;
     334           0 :     sc->u.server=srv;
     335             : 
     336           0 :     TAILQ_INSERT_TAIL(&sock->stun_ctxs,sc,entry);
     337             : 
     338           0 :     *handle=sc;
     339             : 
     340           0 :     _status=0;
     341             :   abort:
     342           0 :     return(_status);
     343             :   }
     344             : 
     345           0 : int nr_ice_socket_register_turn_client(nr_ice_socket *sock, nr_turn_client_ctx *srv,
     346             :                                        nr_socket *turn_socket, void **handle)
     347             :   {
     348           0 :     nr_ice_stun_ctx *sc=0;
     349             :     int _status;
     350             : 
     351           0 :     if(!(sc=RCALLOC(sizeof(nr_ice_stun_ctx))))
     352           0 :       ABORT(R_NO_MEMORY);
     353             : 
     354           0 :     sc->type=NR_ICE_TURN_CLIENT;
     355           0 :     sc->u.turn_client.turn_client=srv;
     356           0 :     sc->u.turn_client.turn_sock=turn_socket;
     357             : 
     358           0 :     TAILQ_INSERT_TAIL(&sock->stun_ctxs,sc,entry);
     359             : 
     360           0 :     *handle=sc;
     361             : 
     362           0 :     _status=0;
     363             :   abort:
     364           0 :     return(_status);
     365             :   }
     366             : 
     367             : /* Just mark it deregistered. Don't delete it now because it's not safe
     368             :    in the CB, which is where this is likely to be called */
     369           0 : int nr_ice_socket_deregister(nr_ice_socket *sock, void *handle)
     370             :   {
     371           0 :     nr_ice_stun_ctx *sc=handle;
     372             : 
     373           0 :     if(!sc)
     374           0 :       return(0);
     375             : 
     376           0 :     sc->type=NR_ICE_STUN_NONE;
     377             : 
     378           0 :     return(0);
     379             :   }
     380             : 

Generated by: LCOV version 1.13