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); }
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); }
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); }
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); }
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); } }
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 }
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 WaitForSocketState_s(TestNrSocket *sock, int state) { NR_ASYNC_WAIT(sock, state, &WaitDone, this); }