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); }
RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& name, bool offerer, bool set_interface_priorities) { RefPtr<NrIceCtx> ctx = new NrIceCtx(name, offerer); // Initialize the crypto callbacks if (!initialized) { NR_reg_init(NR_REG_MODE_LOCAL); nr_crypto_vtbl = &nr_ice_crypto_nss_vtbl; initialized = true; // Set the priorites for candidate type preferences NR_reg_set_uchar((char *)"ice.pref.type.srv_rflx",100); NR_reg_set_uchar((char *)"ice.pref.type.peer_rflx",105); NR_reg_set_uchar((char *)"ice.pref.type.prflx",99); NR_reg_set_uchar((char *)"ice.pref.type.host",125); NR_reg_set_uchar((char *)"ice.pref.type.relayed",126); if (set_interface_priorities) { NR_reg_set_uchar((char *)"ice.pref.interface.rl0", 255); NR_reg_set_uchar((char *)"ice.pref.interface.wi0", 254); NR_reg_set_uchar((char *)"ice.pref.interface.lo0", 253); NR_reg_set_uchar((char *)"ice.pref.interface.en1", 252); NR_reg_set_uchar((char *)"ice.pref.interface.en0", 251); NR_reg_set_uchar((char *)"ice.pref.interface.eth0", 252); NR_reg_set_uchar((char *)"ice.pref.interface.eth1", 251); NR_reg_set_uchar((char *)"ice.pref.interface.eth2", 249); NR_reg_set_uchar((char *)"ice.pref.interface.ppp", 250); NR_reg_set_uchar((char *)"ice.pref.interface.ppp0", 249); NR_reg_set_uchar((char *)"ice.pref.interface.en2", 248); NR_reg_set_uchar((char *)"ice.pref.interface.en3", 247); NR_reg_set_uchar((char *)"ice.pref.interface.em0", 251); NR_reg_set_uchar((char *)"ice.pref.interface.em1", 252); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet0", 240); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet1", 241); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet3", 239); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet4", 238); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet5", 237); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet6", 236); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet7", 235); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet8", 234); NR_reg_set_uchar((char *)"ice.pref.interface.virbr0", 233); NR_reg_set_uchar((char *)"ice.pref.interface.wlan0", 232); } NR_reg_set_string((char *)"ice.stun.server.0.addr", (char *)"216.93.246.14"); NR_reg_set_uint2((char *)"ice.stun.server.0.port",3478); NR_reg_set_uint4((char *)"stun.client.maximum_transmits",4); } // Create the ICE context int r; UINT4 flags = offerer ? NR_ICE_CTX_FLAGS_OFFERER: NR_ICE_CTX_FLAGS_ANSWERER; flags |= NR_ICE_CTX_FLAGS_AGGRESSIVE_NOMINATION; r = nr_ice_ctx_create(const_cast<char *>(name.c_str()), flags, &ctx->ctx_); if (r) { MOZ_MTLOG(PR_LOG_ERROR, "Couldn't create ICE ctx for '" << name << "'"); return nullptr; } // Create the handler objects ctx->ice_handler_vtbl_ = new nr_ice_handler_vtbl(); ctx->ice_handler_vtbl_->select_pair = &NrIceCtx::select_pair; ctx->ice_handler_vtbl_->stream_ready = &NrIceCtx::stream_ready; ctx->ice_handler_vtbl_->stream_failed = &NrIceCtx::stream_failed; ctx->ice_handler_vtbl_->ice_completed = &NrIceCtx::ice_completed; ctx->ice_handler_vtbl_->msg_recvd = &NrIceCtx::msg_recvd; ctx->ice_handler_ = new nr_ice_handler(); ctx->ice_handler_->vtbl = ctx->ice_handler_vtbl_; ctx->ice_handler_->obj = ctx; // Create the peer ctx. Because we do not support parallel forking, we // only have one peer ctx. std::string peer_name = name + ":default"; r = nr_ice_peer_ctx_create(ctx->ctx_, ctx->ice_handler_, const_cast<char *>(peer_name.c_str()), &ctx->peer_); if (r) { MOZ_MTLOG(PR_LOG_ERROR, "Couldn't create ICE peer ctx for '" << name << "'"); return nullptr; } nsresult rv; ctx->sts_target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); if (!NS_SUCCEEDED(rv)) return nullptr; return ctx; }
RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& name, bool offerer, bool allow_loopback, bool tcp_enabled, bool allow_link_local, bool hide_non_default, Policy policy) { RefPtr<NrIceCtx> ctx = new NrIceCtx(name, offerer, policy); // Initialize the crypto callbacks and logging stuff if (!initialized) { NR_reg_init(NR_REG_MODE_LOCAL); nr_crypto_vtbl = &nr_ice_crypto_nss_vtbl; initialized = true; // Set the priorites for candidate type preferences. // These numbers come from RFC 5245 S. 4.1.2.2 NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_SRV_RFLX, 100); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_PEER_RFLX, 110); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_HOST, 126); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_RELAYED, 5); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_SRV_RFLX_TCP, 99); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_PEER_RFLX_TCP, 109); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_HOST_TCP, 125); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_RELAYED_TCP, 0); int32_t stun_client_maximum_transmits = 7; int32_t ice_trickle_grace_period = 5000; int32_t ice_tcp_so_sock_count = 3; int32_t ice_tcp_listen_backlog = 10; nsAutoCString force_net_interface; #ifndef MOZILLA_XPCOMRT_API nsresult res; nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &res); if (NS_SUCCEEDED(res)) { nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs); if (branch) { branch->GetIntPref( "media.peerconnection.ice.stun_client_maximum_transmits", &stun_client_maximum_transmits); branch->GetIntPref( "media.peerconnection.ice.trickle_grace_period", &ice_trickle_grace_period); branch->GetIntPref( "media.peerconnection.ice.tcp_so_sock_count", &ice_tcp_so_sock_count); branch->GetIntPref( "media.peerconnection.ice.tcp_listen_backlog", &ice_tcp_listen_backlog); branch->GetCharPref( "media.peerconnection.ice.force_interface", getter_Copies(force_net_interface)); } } #endif NR_reg_set_uint4((char *)"stun.client.maximum_transmits", stun_client_maximum_transmits); NR_reg_set_uint4((char *)NR_ICE_REG_TRICKLE_GRACE_PERIOD, ice_trickle_grace_period); NR_reg_set_int4((char *)NR_ICE_REG_ICE_TCP_SO_SOCK_COUNT, ice_tcp_so_sock_count); NR_reg_set_int4((char *)NR_ICE_REG_ICE_TCP_LISTEN_BACKLOG, ice_tcp_listen_backlog); NR_reg_set_char((char *)NR_ICE_REG_ICE_TCP_DISABLE, !tcp_enabled); if (allow_loopback) { NR_reg_set_char((char *)NR_STUN_REG_PREF_ALLOW_LOOPBACK_ADDRS, 1); } if (allow_link_local) { NR_reg_set_char((char *)NR_STUN_REG_PREF_ALLOW_LINK_LOCAL_ADDRS, 1); } if (force_net_interface.Length() > 0) { // Stupid cast.... but needed const nsCString& flat = PromiseFlatCString(static_cast<nsACString&>(force_net_interface)); NR_reg_set_string((char *)NR_ICE_REG_PREF_FORCE_INTERFACE_NAME, const_cast<char*>(flat.get())); } } // Create the ICE context int r; UINT4 flags = offerer ? NR_ICE_CTX_FLAGS_OFFERER: NR_ICE_CTX_FLAGS_ANSWERER; flags |= NR_ICE_CTX_FLAGS_AGGRESSIVE_NOMINATION; if (policy == ICE_POLICY_RELAY) { flags |= NR_ICE_CTX_FLAGS_RELAY_ONLY; } if (hide_non_default) flags |= NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS; r = nr_ice_ctx_create(const_cast<char *>(name.c_str()), flags, &ctx->ctx_); if (r) { MOZ_MTLOG(ML_ERROR, "Couldn't create ICE ctx for '" << name << "'"); return nullptr; } nr_interface_prioritizer *prioritizer = CreateInterfacePrioritizer(); if (!prioritizer) { MOZ_MTLOG(LogLevel::Error, "Couldn't create interface prioritizer."); return nullptr; } r = nr_ice_ctx_set_interface_prioritizer(ctx->ctx_, prioritizer); if (r) { MOZ_MTLOG(LogLevel::Error, "Couldn't set interface prioritizer."); return nullptr; } if (ctx->generating_trickle()) { r = nr_ice_ctx_set_trickle_cb(ctx->ctx_, &NrIceCtx::trickle_cb, ctx); if (r) { MOZ_MTLOG(ML_ERROR, "Couldn't set trickle cb for '" << name << "'"); return nullptr; } } // Create the handler objects ctx->ice_handler_vtbl_ = new nr_ice_handler_vtbl(); ctx->ice_handler_vtbl_->select_pair = &NrIceCtx::select_pair; ctx->ice_handler_vtbl_->stream_ready = &NrIceCtx::stream_ready; ctx->ice_handler_vtbl_->stream_failed = &NrIceCtx::stream_failed; ctx->ice_handler_vtbl_->ice_completed = &NrIceCtx::ice_completed; ctx->ice_handler_vtbl_->msg_recvd = &NrIceCtx::msg_recvd; ctx->ice_handler_vtbl_->ice_checking = &NrIceCtx::ice_checking; ctx->ice_handler_ = new nr_ice_handler(); ctx->ice_handler_->vtbl = ctx->ice_handler_vtbl_; ctx->ice_handler_->obj = ctx; // Create the peer ctx. Because we do not support parallel forking, we // only have one peer ctx. std::string peer_name = name + ":default"; r = nr_ice_peer_ctx_create(ctx->ctx_, ctx->ice_handler_, const_cast<char *>(peer_name.c_str()), &ctx->peer_); if (r) { MOZ_MTLOG(ML_ERROR, "Couldn't create ICE peer ctx for '" << name << "'"); return nullptr; } nsresult rv; ctx->sts_target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); if (!NS_SUCCEEDED(rv)) return nullptr; return ctx; }
int main(int argc, char* argv[]) { int verbose = 0; const int maxaddr = 256; nr_transport_addr addresses[maxaddr]; int has_address = 0; StunAddress4 address; int numAddresses = 0; int i; int testNum; int srcPort = 0; printf("STUN client version %s\n",NR_STUN_VERSION); fflush(stdout); nr_crypto_openssl_set(); nr_app_startup("client",NR_APP_STARTUP_INIT_LOGGING|NR_APP_STARTUP_REGISTRY_LOCAL,&NR_LOG_STUN,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.client.level", "debug"); NR_reg_set_string("logging.syslog.facility.stun.level", "debug"); NR_reg_set_string("logging.stderr.facility.client.level", "debug"); NR_reg_set_string("logging.stderr.facility.stun.level", "debug"); if (nr_stun_startup()) { printf("Failed to start STUN\n"); exit(1); } if (initNetwork()) { printf("Failed to start STUN\n"); exit(1); } StunAddress4 stunServerAddr; stunServerAddr.addr=0; int arg; for ( arg = 1; arg<argc; arg++ ) { if ( !strcmp( argv[arg] , "-v" ) ) { verbose = 1; } else if ( !strcmp( argv[arg] , "-n" ) ) { auth_rule = NR_STUN_AUTH_RULE_OPTIONAL; } else if ( !strcmp( argv[arg] , "-s" ) ) { auth_rule = NR_STUN_AUTH_RULE_SHORT_TERM; } else if ( !strcmp( argv[arg] , "-l" ) ) { auth_rule = NR_STUN_AUTH_RULE_LONG_TERM; } #ifdef USE_STUND_0_96 else if ( !strcmp( argv[arg] , "-c" ) ) { stun_mode = NR_STUN_MODE_STUND_0_96; } #endif /* USE_STUND_0_96 */ else if ( !strcmp( argv[arg] , "-p" ) ) { arg++; if ( argc <= arg ) { usage(); exit(-1); } srcPort = strtol( argv[arg], NULL, 10); } else if ( !strcmp( argv[arg] , "-i" ) ) { arg++; if ( argc <= arg ) { usage(); exit(-1); } if (nr_stun_parse_server_name( argv[arg], &address)) { fprintf(stderr,"%s is not a valid host name \n",argv[arg]); fflush(stderr); usage(); exit(-1); } has_address = 1; } else { char* ptr; int t = strtol( argv[arg], &ptr, 10 ); if ( *ptr == 0 ) { // conversion worked testNum = t; printf("running test number %d\n",testNum); fflush(stdout); } else { if (nr_stun_parse_server_name( argv[arg], &stunServerAddr)) { fprintf(stderr,"%s is not a valid host name \n",argv[arg]); usage(); exit(-1); } } } } if (has_address) { if (nr_ip4_port_to_transport_addr(address.addr, srcPort, IPPROTO_UDP, &addresses[0])) { fprintf(stderr,"bad address\n"); exit(1); } numAddresses=1; } if (numAddresses == 0) { if (nr_stun_find_local_addresses(addresses, maxaddr, &numAddresses)) numAddresses = 0; } else if ( srcPort == 0 ) { if (nr_stun_randomPort(&srcPort)) { fprintf(stderr,"Failed\n"); exit(1); } } if (numAddresses == 0) { address.addr = 0; address.port = srcPort; nr_stun_request(&stunServerAddr,1,&address); } else for (i = 0; i < numAddresses; ++i) { address.addr = ntohl(addresses[i].u.addr4.sin_addr.s_addr); address.port = ntohs(addresses[i].u.addr4.sin_port); nr_stun_request(&stunServerAddr,1,&address); } return 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); }
void NrIceCtx::InitializeGlobals(bool allow_loopback, bool tcp_enabled, bool allow_link_local) { // Initialize the crypto callbacks and logging stuff if (!initialized) { NR_reg_init(NR_REG_MODE_LOCAL); nr_crypto_vtbl = &nr_ice_crypto_nss_vtbl; initialized = true; // Set the priorites for candidate type preferences. // These numbers come from RFC 5245 S. 4.1.2.2 NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_SRV_RFLX, 100); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_PEER_RFLX, 110); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_HOST, 126); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_RELAYED, 5); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_SRV_RFLX_TCP, 99); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_PEER_RFLX_TCP, 109); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_HOST_TCP, 125); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_RELAYED_TCP, 0); int32_t stun_client_maximum_transmits = 7; int32_t ice_trickle_grace_period = 5000; int32_t ice_tcp_so_sock_count = 3; int32_t ice_tcp_listen_backlog = 10; nsAutoCString force_net_interface; nsresult res; nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &res); if (NS_SUCCEEDED(res)) { nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs); if (branch) { branch->GetIntPref( "media.peerconnection.ice.stun_client_maximum_transmits", &stun_client_maximum_transmits); branch->GetIntPref( "media.peerconnection.ice.trickle_grace_period", &ice_trickle_grace_period); branch->GetIntPref( "media.peerconnection.ice.tcp_so_sock_count", &ice_tcp_so_sock_count); branch->GetIntPref( "media.peerconnection.ice.tcp_listen_backlog", &ice_tcp_listen_backlog); branch->GetCharPref( "media.peerconnection.ice.force_interface", getter_Copies(force_net_interface)); } } NR_reg_set_uint4((char *)"stun.client.maximum_transmits", stun_client_maximum_transmits); NR_reg_set_uint4((char *)NR_ICE_REG_TRICKLE_GRACE_PERIOD, ice_trickle_grace_period); NR_reg_set_int4((char *)NR_ICE_REG_ICE_TCP_SO_SOCK_COUNT, ice_tcp_so_sock_count); NR_reg_set_int4((char *)NR_ICE_REG_ICE_TCP_LISTEN_BACKLOG, ice_tcp_listen_backlog); NR_reg_set_char((char *)NR_ICE_REG_ICE_TCP_DISABLE, !tcp_enabled); if (allow_loopback) { NR_reg_set_char((char *)NR_STUN_REG_PREF_ALLOW_LOOPBACK_ADDRS, 1); } if (allow_link_local) { NR_reg_set_char((char *)NR_STUN_REG_PREF_ALLOW_LINK_LOCAL_ADDRS, 1); } if (force_net_interface.Length() > 0) { // Stupid cast.... but needed const nsCString& flat = PromiseFlatCString(static_cast<nsACString&>(force_net_interface)); NR_reg_set_string((char *)NR_ICE_REG_PREF_FORCE_INTERFACE_NAME, const_cast<char*>(flat.get())); } } }
int main(int argc, char* argv[]) { StunAddress4 myAddr; int myPort = 0; char verbose=0; char background=0; printf("STUN server version %s\n",NR_STUN_VERSION); fflush(stdout); nr_crypto_openssl_set(); nr_app_startup("server",NR_APP_STARTUP_INIT_LOGGING|NR_APP_STARTUP_REGISTRY_LOCAL,&NR_LOG_STUN,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.server.level", "debug"); NR_reg_set_string("logging.syslog.facility.stun.level", "debug"); NR_reg_set_string("logging.stderr.facility.client.level", "debug"); NR_reg_set_string("logging.stderr.facility.stun.level", "debug"); if (nr_stun_startup()) { printf("Failed to start STUN\n"); exit(1); } if (initNetwork()) { printf("Failed to start STUN\n"); exit(1); } myAddr.addr = 0; myAddr.port = NR_STUN_PORT; if ( argc <= 2 ) { usage(); exit(-1); } int arg; for ( arg = 1; arg<argc; arg++ ) { if ( !strcmp( argv[arg] , "-v" ) ) { verbose = 1; } else if ( !strcmp( argv[arg] , "-b" ) ) { background = 1; } else if ( !strcmp( argv[arg] , "-a" ) ) { alternate_server = 1; } else if ( !strcmp( argv[arg] , "-h" ) ) { arg++; if ( argc <= arg ) { usage(); exit(-1); } if (nr_stun_parse_server_name(argv[arg], &myAddr)) { usage(); exit(-1); } } else if ( !strcmp( argv[arg] , "-p" ) ) { arg++; if ( argc <= arg ) { usage(); exit(-1); } myPort = (UINT2)(strtol( argv[arg], NULL, 10)); } else { usage(); exit(-1); } } if ( myPort != 0 ) { myAddr.port = myPort; } if ( ( myAddr.addr == 0 ) || ( myAddr.port == 0 ) ) { fprintf(stderr,"Bad command line\n"); fflush(stderr); exit(1); } #if defined(WIN32) int pid=0; if ( background ) { fprintf(stderr,"The -b background option does not work in windows\n"); fflush(stderr); exit(-1); } #else pid_t pid=0; if ( background ) { pid = fork(); if (pid < 0) { fprintf(stderr,"fork: unable to fork\n"); fflush(stderr); exit(-1); } } #endif if (pid == 0) //child or not using background { StunServerInfo info; char ok = 1; if (nr_stun_init_server(&info, &myAddr)) ok = 0; int c=0; while (ok) { if (nr_stun_server_process(&info)) { fprintf(stderr,"Failed\n"); exit(1); } c++; if ( c%10000 == 0 ) { printf("*"); fflush(stdout); } } } return 0; }