media/mtransport/third_party/nICEr/src/ice/ice_socket.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /*
     2 Copyright (c) 2007, Adobe Systems, Incorporated
     3 All rights reserved.
     5 Redistribution and use in source and binary forms, with or without
     6 modification, are permitted provided that the following conditions are
     7 met:
     9 * Redistributions of source code must retain the above copyright
    10   notice, this list of conditions and the following disclaimer.
    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.
    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.
    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 */
    35 static char *RCSSTRING __UNUSED__="$Id: ice_socket.c,v 1.2 2008/04/28 17:59:01 ekr Exp $";
    37 #include <assert.h>
    38 #include <string.h>
    39 #include "nr_api.h"
    40 #include "ice_ctx.h"
    41 #include "stun.h"
    43 static void nr_ice_socket_readable_cb(NR_SOCKET s, int how, void *cb_arg)
    44   {
    45     int r;
    46     nr_ice_stun_ctx *sc1,*sc2;
    47     nr_ice_socket *sock=cb_arg;
    48     UCHAR buf[8192];
    49     char string[256];
    50     nr_transport_addr addr;
    51     int len;
    52     size_t len_s;
    53     int is_stun;
    54     int is_req;
    55     int is_ind;
    56     int processed_indication=0;
    58     nr_socket *stun_srv_sock=sock->sock;
    60     r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Socket ready to read",sock->ctx->label);
    62     /* Re-arm first! */
    63     NR_ASYNC_WAIT(s,how,nr_ice_socket_readable_cb,cb_arg);
    65     if(r=nr_socket_recvfrom(sock->sock,buf,sizeof(buf),&len_s,0,&addr)){
    66       if (r != R_WOULDBLOCK && (sock->type != NR_ICE_SOCKET_TYPE_DGRAM)) {
    67         /* Report this error upward. Bug 946423 */
    68         r_log(LOG_ICE,LOG_ERR,"ICE(%s): Error on reliable socket. Abandoning.",sock->ctx->label);
    69         NR_ASYNC_CANCEL(s, NR_ASYNC_WAIT_READ);
    70       }
    71       return;
    72     }
    74     /* Deal with the fact that sizeof(int) and sizeof(size_t) may not
    75        be the same */
    76     if (len_s > (size_t)INT_MAX)
    77       return;
    79     len = (int)len_s;
    81 #ifdef USE_TURN
    82   re_process:
    83 #endif /* USE_TURN */
    84     r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Read %d bytes %sfrom %s",sock->ctx->label,len,(processed_indication ? "relayed " : ""),addr.as_string);
    86     /* First question: is this STUN or not? */
    87     is_stun=nr_is_stun_message(buf,len);
    89     if(is_stun){
    90       is_req=nr_is_stun_request_message(buf,len);
    91       is_ind=is_req?0:nr_is_stun_indication_message(buf,len);
    93       snprintf(string, sizeof(string)-1, "ICE(%s): Message is STUN (%s)",sock->ctx->label,
    94                is_req ? "request" : (is_ind ? "indication" : "other"));
    95       r_dump(NR_LOG_STUN, LOG_DEBUG, string, (char*)buf, len);
    98       /* We need to offer it to all of our stun contexts
    99          to see who bites */
   100       sc1=TAILQ_FIRST(&sock->stun_ctxs);
   101       while(sc1){
   102         sc2=TAILQ_NEXT(sc1,entry);
   104         r=-1;
   105         switch(sc1->type){
   106           /* This has been deleted, prune... */
   107           case NR_ICE_STUN_NONE:
   108             TAILQ_REMOVE(&sock->stun_ctxs,sc1,entry);
   109             RFREE(sc1);
   110             break;
   112           case NR_ICE_STUN_CLIENT:
   113             if(!(is_req||is_ind)){
   114                 r=nr_stun_client_process_response(sc1->u.client,buf,len,&addr);
   115             }
   116             break;
   118           case NR_ICE_STUN_SERVER:
   119             if(is_req){
   120               r=nr_stun_server_process_request(sc1->u.server,stun_srv_sock,(char *)buf,len,&addr,NR_STUN_AUTH_RULE_SHORT_TERM);
   121             }
   122             break;
   123 #ifdef USE_TURN
   124           case NR_ICE_TURN_CLIENT:
   125             /* data indications are ok, so don't ignore those */
   126             /* Check that this is from the right TURN server address. Else
   127                skip */
   128             if (nr_transport_addr_cmp(
   129                     &sc1->u.turn_client.turn_client->turn_server_addr,
   130                     &addr, NR_TRANSPORT_ADDR_CMP_MODE_ALL))
   131               break;
   133             if(!is_req){
   134               if(!is_ind)
   135                 r=nr_turn_client_process_response(sc1->u.turn_client.turn_client,buf,len,&addr);
   136               else{
   137                 nr_transport_addr n_addr;
   138                 size_t n_len;
   140                 if (processed_indication) {
   141                   /* Don't allow recursively wrapped indications */
   142                   r_log(LOG_ICE, LOG_WARNING,
   143                         "ICE(%s): discarding recursively wrapped indication",
   144                         sock->ctx->label);
   145                   break;
   146                 }
   147                 /* This is a bit of a hack. If it's a data indication, strip
   148                    off the TURN framing and re-enter. This works because
   149                    all STUN processing is on the same physical socket.
   150                    We don't care about other kinds of indication */
   151                 r=nr_turn_client_parse_data_indication(
   152                     sc1->u.turn_client.turn_client, &addr,
   153                     buf, len, buf, &n_len, len, &n_addr);
   154                 if(!r){
   155                   r_log(LOG_ICE,LOG_DEBUG,"Unwrapped a data indication.");
   156                   len=n_len;
   157                   nr_transport_addr_copy(&addr,&n_addr);
   158                   stun_srv_sock=sc1->u.turn_client.turn_sock;
   159                   processed_indication=1;
   160                   goto re_process;
   161                 }
   162               }
   163             }
   164             break;
   165 #endif /* USE_TURN */
   167           default:
   168             assert(0); /* Can't happen */
   169             return;
   170         }
   171         if(!r) {
   172           break;
   173         }
   175         sc1=sc2;
   176       }
   177       if(!sc1){
   178         if (nr_ice_ctx_is_known_id(sock->ctx,((nr_stun_message_header*)buf)->id.octet))
   179             r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Message is a retransmit",sock->ctx->label);
   180         else
   181             r_log(LOG_ICE,LOG_NOTICE,"ICE(%s): Message does not correspond to any registered stun ctx",sock->ctx->label);
   182       }
   183     }
   184     else{
   185       r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Message is not STUN",sock->ctx->label);
   187       nr_ice_ctx_deliver_packet(sock->ctx, sock->component, &addr, buf, len);
   188     }
   190     return;
   191   }
   193 int nr_ice_socket_create(nr_ice_ctx *ctx,nr_ice_component *comp, nr_socket *nsock, nr_ice_socket **sockp)
   194   {
   195     nr_ice_socket *sock=0;
   196     NR_SOCKET fd;
   197     nr_transport_addr addr;
   198     int r,_status;
   200     if(!(sock=RCALLOC(sizeof(nr_ice_socket))))
   201       ABORT(R_NO_MEMORY);
   203     sock->sock=nsock;
   204     sock->ctx=ctx;
   205     sock->component=comp;
   207     if(r=nr_socket_getaddr(nsock, &addr))
   208       ABORT(r);
   210     if (addr.protocol == IPPROTO_UDP) {
   211       sock->type = NR_ICE_SOCKET_TYPE_DGRAM;
   212     }
   213     else {
   214       assert(addr.protocol == IPPROTO_TCP);
   215       sock->type = NR_ICE_SOCKET_TYPE_STREAM;
   216     }
   218     TAILQ_INIT(&sock->candidates);
   219     TAILQ_INIT(&sock->stun_ctxs);
   221     if(r=nr_socket_getfd(nsock,&fd))
   222       ABORT(r);
   224     NR_ASYNC_WAIT(fd,NR_ASYNC_WAIT_READ,nr_ice_socket_readable_cb,sock);
   226     *sockp=sock;
   228     _status=0;
   229   abort:
   230     if(_status) RFREE(sock);
   231     return(_status);
   232   }
   235 int nr_ice_socket_destroy(nr_ice_socket **isockp)
   236   {
   237     nr_ice_stun_ctx *s1,*s2;
   238     nr_ice_socket *isock;
   240     if(!isockp || !*isockp)
   241       return(0);
   243     isock=*isockp;
   244     *isockp=0;
   246     /* Close the socket */
   247     nr_ice_socket_close(isock);
   249     /* The STUN server */
   250     nr_stun_server_ctx_destroy(&isock->stun_server);
   252     /* Now clean up the STUN ctxs */
   253     TAILQ_FOREACH_SAFE(s1, &isock->stun_ctxs, entry, s2){
   254       TAILQ_REMOVE(&isock->stun_ctxs, s1, entry);
   255       RFREE(s1);
   256     }
   258     RFREE(isock);
   260     return(0);
   261   }
   263 int nr_ice_socket_close(nr_ice_socket *isock)
   264   {
   265 #ifdef NR_SOCKET_IS_VOID_PTR
   266     NR_SOCKET fd=NULL;
   267     NR_SOCKET no_socket = NULL;
   268 #else
   269     NR_SOCKET fd=-1;
   270     NR_SOCKET no_socket = -1;
   271 #endif
   273     if (!isock||!isock->sock)
   274       return(0);
   276     nr_socket_getfd(isock->sock,&fd);
   277     assert(isock->sock!=0);
   278     if(fd != no_socket){
   279       NR_ASYNC_CANCEL(fd,NR_ASYNC_WAIT_READ);
   280       NR_ASYNC_CANCEL(fd,NR_ASYNC_WAIT_WRITE);
   281       nr_socket_destroy(&isock->sock);
   282     }
   284     return(0);
   285   }
   287 int nr_ice_socket_register_stun_client(nr_ice_socket *sock, nr_stun_client_ctx *srv,void **handle)
   288   {
   289     nr_ice_stun_ctx *sc=0;
   290     int _status;
   292     if(!(sc=RCALLOC(sizeof(nr_ice_stun_ctx))))
   293       ABORT(R_NO_MEMORY);
   295     sc->type=NR_ICE_STUN_CLIENT;
   296     sc->u.client=srv;
   298     TAILQ_INSERT_TAIL(&sock->stun_ctxs,sc,entry);
   300     *handle=sc;
   302     _status=0;
   303   abort:
   304     return(_status);
   305   }
   307 int nr_ice_socket_register_stun_server(nr_ice_socket *sock, nr_stun_server_ctx *srv,void **handle)
   308   {
   309     nr_ice_stun_ctx *sc=0;
   310     int _status;
   312     if(!(sc=RCALLOC(sizeof(nr_ice_stun_ctx))))
   313       ABORT(R_NO_MEMORY);
   315     sc->type=NR_ICE_STUN_SERVER;
   316     sc->u.server=srv;
   318     TAILQ_INSERT_TAIL(&sock->stun_ctxs,sc,entry);
   320     *handle=sc;
   322     _status=0;
   323   abort:
   324     return(_status);
   325   }
   327 int nr_ice_socket_register_turn_client(nr_ice_socket *sock, nr_turn_client_ctx *srv,
   328                                        nr_socket *turn_socket, void **handle)
   329   {
   330     nr_ice_stun_ctx *sc=0;
   331     int _status;
   333     if(!(sc=RCALLOC(sizeof(nr_ice_stun_ctx))))
   334       ABORT(R_NO_MEMORY);
   336     sc->type=NR_ICE_TURN_CLIENT;
   337     sc->u.turn_client.turn_client=srv;
   338     sc->u.turn_client.turn_sock=turn_socket;
   340     TAILQ_INSERT_TAIL(&sock->stun_ctxs,sc,entry);
   342     *handle=sc;
   344     _status=0;
   345   abort:
   346     return(_status);
   347   }
   349 /* Just mark it deregistered. Don't delete it now because it's not safe
   350    in the CB, which is where this is likely to be called */
   351 int nr_ice_socket_deregister(nr_ice_socket *sock, void *handle)
   352   {
   353     nr_ice_stun_ctx *sc=handle;
   355     if(!sc)
   356       return(0);
   358     sc->type=NR_ICE_STUN_NONE;
   360     return(0);
   361   }

mercurial