Пример #1
0
int main(int argc, char **argv)
  {
    int r;
    nr_transport_addr my_addr;
    nr_socket *my_sock;
    int fd;
    struct timeval tv;

    if (argc != 1) 
        usage();

    nr_app_startup("turn_server",NR_APP_STARTUP_INIT_LOGGING|NR_APP_STARTUP_REGISTRY_LOCAL,&LOG_TURN_SERVER,0,0);
NR_reg_set_char("logging.stderr.enabled", 1);
NR_reg_set_char("logging.syslog.enabled", 1);
NR_reg_set_string("logging.syslog.facility.turn_client.level", "debug");
NR_reg_set_string("logging.stderr.facility.turn_client.level", "debug");
NR_reg_set_string("logging.syslog.facility.stun.level", "debug");
NR_reg_set_string("logging.stderr.facility.stun.level", "debug");
NR_reg_set_string("logging.syslog.facility.turn.level", "debug");
NR_reg_set_string("logging.stderr.facility.turn.level", "debug");
 
    NR_async_timer_init();
    gettimeofday(&tv,0);
    NR_async_timer_update_time(&tv);

    /* Set up the TURN client */
    nr_ip4_port_to_transport_addr(ntohl(0), 3478, IPPROTO_UDP, &my_addr);
    if(r=nr_socket_local_create(&my_addr,&my_sock)){
      fprintf(stderr,"Couldn't create socket\n");
      exit(1);
    }

    /* Now set an async cb */
    nr_socket_getfd(my_sock,&fd);
    NR_ASYNC_WAIT(fd,NR_ASYNC_WAIT_READ,s_cb,my_sock);
 
    while(1){
      int events;
      struct timeval towait={0,50};

      if(r=NR_async_event_wait2(&events,&towait)){
#if 0
        if(r==R_EOD)
          break;
        
        if(r!=R_WOULDBLOCK){
          fprintf(stderr,"Error in event wait\n");
          exit(1);
        }
#endif
      }

      gettimeofday(&tv,0);
      NR_async_timer_update_time(&tv);
    }

    printf("Success!\n");

    exit(0);
  }
Пример #2
0
static int nr_turn_client_connect(nr_turn_client_ctx *ctx)
{
  int r,_status;

  if (ctx->turn_server_addr.protocol != IPPROTO_TCP)
    ABORT(R_INTERNAL);

  r = nr_socket_connect(ctx->sock, &ctx->turn_server_addr);

  if (r == R_WOULDBLOCK) {
    NR_SOCKET fd;

    if (r=nr_socket_getfd(ctx->sock, &fd))
      ABORT(r);

    NR_ASYNC_WAIT(fd, NR_ASYNC_WAIT_WRITE, nr_turn_client_connected_cb, ctx);
    NR_ASYNC_TIMER_SET(TURN_CONNECT_TIMEOUT,
                       nr_turn_client_connect_timeout_cb, ctx,
                       &ctx->connected_timer_handle);
    ABORT(R_WOULDBLOCK);
  }
  if (r) {
    ABORT(R_IO_ERROR);
  }

  ctx->state = NR_TURN_CLIENT_STATE_CONNECTED;

  _status = 0;
abort:
  return(_status);
}
Пример #3
0
static int nr_tcp_socket_ctx_initialize(nr_tcp_socket_ctx *tcpsock,
  nr_transport_addr *addr, void* cb_arg)
  {
    int r, _status;
    NR_SOCKET fd;

    if ((r=nr_transport_addr_copy(&tcpsock->remote_addr, addr)))
      ABORT(r);
    if ((r=nr_socket_getfd(tcpsock->inner, &fd)))
      ABORT(r);
    NR_ASYNC_WAIT(fd, NR_ASYNC_WAIT_READ, nr_tcp_socket_readable_cb, cb_arg);

    _status=0;
  abort:
    if (_status)
      r_log(LOG_ICE,LOG_DEBUG,"%s:%d function %s(addr:%s) failed with error %d",__FILE__,__LINE__,__FUNCTION__,addr->as_string,_status);
    return(_status);
  }
Пример #4
0
void c_cb(int s, int how, void *cb_arg)
  {
    nr_turn_client_ctx *turn=cb_arg;
    UCHAR buf2[4096];
    size_t len;
    nr_transport_addr addr2;
    int r;

    fprintf(stderr,"TURN_CLIENT: CLIENT CB\n");

    if(r=nr_socket_recvfrom(turn->sock,buf2,sizeof(buf2),&len,0,&addr2)){
      fprintf(stderr,"Error in recvfrom\n");
      exit(1);
    }

    if(r=nr_turn_client_process_response(turn, buf2, len, &addr2)){
        fprintf(stderr,"Error processing TURN response, ignoring\n");
    }

    NR_ASYNC_WAIT(s, how, c_cb, cb_arg);
  }
Пример #5
0
void TestNrSocket::write_to_port_mapping(NrSocketBase *external_socket) {
  MOZ_ASSERT(internal_socket_->my_addr().protocol != IPPROTO_TCP);

  int r = 0;
  for (PortMapping *port_mapping : port_mappings_) {
    if (port_mapping->external_socket_ == external_socket) {
      // If the send succeeds, or if there was nothing to send, we keep going
      r = port_mapping->send_from_queue();
      if (r) {
        break;
      }
    }
  }

  if (r == R_WOULDBLOCK) {
    // Re-register for writeable callbacks, since we still have stuff to send
    NR_ASYNC_WAIT(external_socket,
                  NR_ASYNC_WAIT_WRITE,
                  &TestNrSocket::port_mapping_writeable_callback,
                  this);
  }
}
Пример #6
0
static void s_cb(int s, int how, void *cb_arg)
  {
#if 0
    nr_socket *sock = (nr_socket*)cb_arg;
    UCHAR buf2[4096];
    size_t len;
    nr_transport_addr addr2;
    int r;
    StunMessage req;
    StunMessage res;
    //StunAddress4 from;

    fprintf(stderr,"TURN_SERVER_UTIL: SERVER CB\n");

    if(r=nr_socket_recvfrom(sock,buf2,sizeof(buf2),&len,0,&addr2)){
      fprintf(stderr,"Error in recvfrom\n");
      exit(1);
    }

    memset(&req, 0, sizeof(req));
    memset(&res, 0, sizeof(res));
    //memset(&from, 0, sizeof(from));
    //from.addr = ntohl(addr2.u.addr4.sin_addr.s_addr);
    //from.port = ntohs(addr2.u.addr4.sin_port);

    if ((r=nr_stun_parse_message((char*)buf2, len, &req))) {
      fprintf(stderr,"Error in nr_stun_parse_message\n");
      exit(1);
    }

    if ((r=nr_stun_process_request(&req, buf2, len, &addr2, 0, 0, &res))) {
        /* failure is expected because the server code doesn't support TURN */
        if (r!=R_FAILED) {
            fprintf(stderr,"Failed to process message!\n");
            exit(1);
        }
        fprintf(stderr,"TURN_SERVER_UTIL: No problem with parse failure ... process TURN in test server code\n");
    }

    if (!nr_is_stun_message((char*)buf2, len)) {
        fprintf(stderr,"TURN_SERVER_UTIL: not a STUN/TURN message\n");
        /* instead of sending to remoteAddress, just echo the content back
         * for the purposes of our tests */
        goto send;
    }

    res.hasFingerprint = 1;

    switch (req.msgHdr.msgType) {
    case AllocateRequestMsg:
       if (! req.hasNonce) {
           fprintf(stderr, "Received AllocateRequestMsg #1\n");
           assert(!req.hasMessageIntegrity);
/* TODO: what about username: does it go into the req or not? spec not clear */
           res.msgHdr.msgType = AllocateErrorResponseMsg;
           res.hasUsername = 0;
           res.hasNonce = 1;
           strcpy(res.nonce, nonce);
           res.hasRealm = 1;
           strcpy(res.realm, "REALM");
           res.hasErrorCode = 1;
           res.errorCode.errorClass = 4;
           res.errorCode.number = 35;
       }
       else {
           fprintf(stderr, "Received AllocateRequestMsg #2\n");
           assert(req.hasUsername);
           assert(req.hasRealm);
           assert(req.hasNonce);
           assert(req.hasMessageIntegrity);
           res.msgHdr.msgType = AllocateResponseMsg;
           res.hasUsername = 1;
           res.hasMessageIntegrity = 1;
           strcpy(res.username, req.username);
#if 0
//TODO: this is totally broken, but TURN is changing and so
//TODO: we'll need to take another pass at all this code
//TODO: anyhow, so leave it broken for now
           res.hasRelayAddress = 1;
           res.relayAddress.family = IPv4Family;
           res.relayAddress.ipv4.addr = from.addr;
           res.relayAddress.ipv4.port = from.port;
           res.hasXorMappedAddress = 1;
           res.xorMappedAddress.family = IPv4Family;
           res.xorMappedAddress.ipv4.addr = from.addr;
           res.xorMappedAddress.ipv4.port = from.port;
#endif
       }
       break;
    case SendIndicationMsg:
       fprintf(stderr, "Received SendIndicationMsg\n");
       assert(req.hasRemoteAddress);

       /* pretend to send empty UDP packet to remoteAddress per the
        * TURN spec and to wait for a DataIndication resonse */
       fprintf(stderr, "Sending UDP packet to REMOTE-ADDRESS...\n");
       fprintf(stderr, "Waiting for response from REMOTE-ADDRESS...\n");

       /* ok, this is an indication, so formally there is no "response",
        * but we're going to send a data indication to it, so just pretend
        * that it's a formal response */
       res.msgHdr.msgType = DataIndicationMsg;
       res.hasRemoteAddress = 1;
       nr_transport_addr_copy(&res.remoteAddress, &req.remoteAddress);

       break;
    case SetActiveDestRequestMsg:
       fprintf(stderr, "Received SetActiveDestRequestMsg\n");
       assert(req.hasRemoteAddress);
 
       res.msgHdr.msgType = SetActiveDestResponseMsg;
       break;
    default:
       assert(0);
       break;
    }

   memset(&buf2, 0, sizeof(buf2));

   if ((r=nr_stun_encode_message(STUN_MODE_STUN, &res, (char*)buf2, STUN_MAX_MESSAGE_SIZE, &pass, (unsigned int*)&len))) {
      fprintf(stderr,"Error encoding TURN response\n");
      exit(1);
    }

 send:
   fprintf(stderr,"Sending response to %s\n", addr2.as_string);
   if(r=nr_socket_sendto(sock,buf2,len,0,&addr2)) {
      fprintf(stderr,"Error sending TURN response\n");
      exit(1);
    }

    NR_ASYNC_WAIT(s, how, s_cb, cb_arg);
#else
UNIMPLEMENTED;
#endif
  }
Пример #7
0
int main(int argc, char **argv)
  {
    int r;
    nr_turn_client_ctx *c_turn;
    nr_transport_addr my_addr;
    nr_socket *my_sock;
    int fd;
    struct timeval tv;

    nr_crypto_openssl_set();

    if (argc != 2) 
        usage();

    nr_app_startup("turn_client",NR_APP_STARTUP_INIT_LOGGING|NR_APP_STARTUP_REGISTRY_LOCAL,&LOG_TURN_CLIENT,0,0);
NR_reg_set_char("logging.stderr.enabled", 1);
NR_reg_set_char("logging.syslog.enabled", 1);
NR_reg_set_string("logging.syslog.facility.turn_client.level", "debug");
NR_reg_set_string("logging.stderr.facility.turn_client.level", "debug");
NR_reg_set_string("logging.syslog.facility.stun.level", "debug");
NR_reg_set_string("logging.stderr.facility.stun.level", "debug");
NR_reg_set_string("logging.syslog.facility.turn.level", "debug");
NR_reg_set_string("logging.stderr.facility.turn.level", "debug");
 
    NR_async_timer_init();
    gettimeofday(&tv,0);
    NR_async_timer_update_time(&tv);

    nr_ip4_port_to_transport_addr(ntohl(inet_addr(argv[1])),
      3478,IPPROTO_UDP,&remote_addr);

    /* Set up the TURN client */
    nr_ip4_port_to_transport_addr(ntohl(0), 0, IPPROTO_UDP, &my_addr);
    if(r=nr_socket_local_create(&my_addr,&my_sock)){
      fprintf(stderr,"Couldn't create socket\n");
      exit(1);
    }

    if(r=nr_turn_client_ctx_create("TEST",my_sock, 0, &remote_addr,0, &c_turn)){
      fprintf(stderr,"Couldn't create TURN ctx\n");
      exit(1);
    }

    /* Start TURN */
    if(r=nr_turn_client_allocate(c_turn, user, &pass, 123456, 654321, done_cb, c_turn)){
      fprintf(stderr,"Couldn't start TURN\n");
      exit(1);
    }

    /* Now set an async cb */
    nr_socket_getfd(my_sock,&fd);
    NR_ASYNC_WAIT(fd,NR_ASYNC_WAIT_READ,c_cb,c_turn);
 
    while(1){
      int events;
      struct timeval towait={0,50};

      if(r=NR_async_event_wait2(&events,&towait)){
#if 0
        if(r==R_EOD)
          break;
        
        if(r!=R_WOULDBLOCK){
          fprintf(stderr,"Error in event wait\n");
          exit(1);
        }
#endif
      }

      gettimeofday(&tv,0);
      NR_async_timer_update_time(&tv);
    }

    printf("Success!\n");

    exit(0);
  }
Пример #8
0
 void WaitForSocketState_s(TestNrSocket *sock, int state) {
     NR_ASYNC_WAIT(sock, state, &WaitDone, this);
 }