static int init_server(tls_listener_relay_server_type* server, const char* ifname, const char *local_address, int port, int verbose, ioa_engine_handle e, ioa_engine_new_connection_event_handler send_socket, struct relay_server *relay_server) { if(!server) return -1; server->connect_cb = send_socket; server->relay_server = relay_server; if(ifname) STRCPY(server->ifname,ifname); if(make_ioa_addr((const u08bits*)local_address, port, &server->addr)<0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot create a TCP/TLS listener for address: %s\n",local_address); return -1; } server->verbose=verbose; server->e = e; return create_server_listener(server); }
static int init_server(dtls_listener_relay_server_type* server, const char* ifname, const char *local_address, int port, int verbose, ioa_engine_handle e, turn_turnserver *ts) { if(!server) return -1; server->dtls_ctx = e->dtls_ctx; server->ts = ts; server->children_ss = ur_addr_map_create(65535); if(ifname) STRCPY(server->ifname,ifname); if(make_ioa_addr((const u08bits*)local_address, port, &server->addr)<0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot create a UDP/DTLS listener for address: %s\n",local_address); return -1; } server->slen0 = get_ioa_addr_len(&(server->addr)); server->verbose=verbose; server->e = e; TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"IO method: %s\n",event_base_get_method(server->e->event_base)); if(server->dtls_ctx) { #if defined(REQUEST_CLIENT_CERT) /* If client has to authenticate, then */ SSL_CTX_set_verify(server->dtls_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, dtls_verify_callback); #endif SSL_CTX_set_read_ahead(server->dtls_ctx, 1); #if !defined(TURN_NO_DTLS) SSL_CTX_set_cookie_generate_cb(server->dtls_ctx, generate_cookie); SSL_CTX_set_cookie_verify_cb(server->dtls_ctx, verify_cookie); #endif } return create_server_socket(server); }
static int udp_create_server_socket(server_type* server, const char* ifname, const char *local_address, int port) { FUNCSTART; if(!server) return -1; evutil_socket_t udp_fd = -1; ioa_addr *server_addr = (ioa_addr*)malloc(sizeof(ioa_addr)); STRCPY(server->ifname,ifname); if(make_ioa_addr((const u08bits*)local_address, port, server_addr)<0) return -1; udp_fd = socket(server_addr->ss.ss_family, SOCK_DGRAM, 0); if (udp_fd < 0) { perror("socket"); return -1; } if(sock_bind_to_device(udp_fd, (unsigned char*)server->ifname)<0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind udp server socket to device %s\n",server->ifname); } set_sock_buf_size(udp_fd,UR_SERVER_SOCK_BUF_SIZE); if(addr_bind(udp_fd,server_addr)<0) return -1; evutil_make_socket_nonblocking(udp_fd); struct event *udp_ev = event_new(server->event_base,udp_fd,EV_READ|EV_PERSIST, udp_server_input_handler,server_addr); event_add(udp_ev,NULL); FUNCEND; return 0; }
static int init_server(tcp_listener_relay_server_type* server, const char* ifname, const char *local_address, int port, int verbose, ioa_engine_handle e, uint32_t *stats) { if(!server) return -1; server->stats=stats; if(ifname) STRCPY(server->ifname,ifname); if(make_ioa_addr((const u08bits*)local_address, port, &server->addr)<0) { return -1; } server->verbose=verbose; server->e = e; return create_server_listener(server); }
int main(int argc, char **argv) { int port = 0; int messagenumber = 5; char local_addr[256]; int c; int mclient = 1; char peer_address[129] = "\0"; int peer_port = PEER_DEFAULT_PORT; char rest_api_separator = ':'; int use_null_cipher=0; set_logfile("stdout"); set_execdir(); set_system_parameters(0); ns_bzero(local_addr, sizeof(local_addr)); while ((c = getopt(argc, argv, "d:p:l:n:L:m:e:r:u:w:i:k:z:W:C:E:F:vsyhcxXgtTSAPDNOUHMRIGB")) != -1) { switch (c){ case 'B': random_disconnect = 1; break; case 'G': extra_requests = 1; break; case 'F': STRCPY(cipher_suite,optarg); break; case 'I': no_permissions = 1; break; case 'M': mobility = 1; break; case 'H': shatype = SHATYPE_SHA256; break; case 'E': { char* fn = find_config_file(optarg,1); if(!fn) { fprintf(stderr,"ERROR: file %s not found\n",optarg); exit(-1); } STRCPY(ca_cert_file,fn); } break; case 'O': dos = 1; break; case 'C': rest_api_separator=*optarg; break; case 'D': mandatory_channel_padding = 1; break; case 'N': negative_test = 1; break; case 'R': negative_protocol_test = 1; break; case 'z': RTP_PACKET_INTERVAL = atoi(optarg); break; case 'A': use_short_term = 1; break; case 'u': STRCPY(g_uname, optarg); break; case 'w': STRCPY(g_upwd, optarg); break; case 'g': dont_fragment = 1; break; case 'd': STRCPY(client_ifname, optarg); break; case 'x': default_address_family = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; break; case 'X': default_address_family = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4; break; case 'l': clmessage_length = atoi(optarg); break; case 's': do_not_use_channel = 1; break; case 'n': messagenumber = atoi(optarg); break; case 'p': port = atoi(optarg); break; case 'L': STRCPY(local_addr, optarg); break; case 'e': STRCPY(peer_address, optarg); break; case 'r': peer_port = atoi(optarg); break; case 'v': clnet_verbose = TURN_VERBOSE_NORMAL; break; case 'h': hang_on = 1; break; case 'c': no_rtcp = 1; break; case 'm': mclient = atoi(optarg); break; case 'y': c2c = 1; break; case 't': use_tcp = 1; break; case 'P': passive_tcp = 1; /* implies 'T': */ /* no break */ case 'T': relay_transport = STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE; break; case 'U': use_null_cipher = 1; /* implies 'S' */ /* no break */ case 'S': use_secure = 1; break; case 'W': g_use_auth_secret_with_timestamp = 1; STRCPY(g_auth_secret,optarg); break; case 'i': { char* fn = find_config_file(optarg,1); if(!fn) { fprintf(stderr,"ERROR: file %s not found\n",optarg); exit(-1); } STRCPY(cert_file,fn); free(fn); } break; case 'k': { char* fn = find_config_file(optarg,1); if(!fn) { fprintf(stderr,"ERROR: file %s not found\n",optarg); exit(-1); } STRCPY(pkey_file,fn); free(fn); } break; default: fprintf(stderr, "%s\n", Usage); exit(1); } } if(g_use_auth_secret_with_timestamp) { if(use_short_term) { fprintf(stderr,"ERROR: You cannot use authentication secret (REST API) with short-term credentials mechanism.\n"); exit(-1); } { char new_uname[1025]; const unsigned long exp_time = 3600 * 24; /* one day */ if(g_uname[0]) { snprintf(new_uname,sizeof(new_uname),"%lu%c%s",(unsigned long)time(NULL) + exp_time,rest_api_separator, (char*)g_uname); } else { snprintf(new_uname,sizeof(new_uname),"%lu", (unsigned long)time(NULL) + exp_time); } STRCPY(g_uname,new_uname); } { u08bits hmac[MAXSHASIZE]; unsigned int hmac_len; switch(shatype) { case SHATYPE_SHA256: hmac_len = SHA256SIZEBYTES; break; default: hmac_len = SHA1SIZEBYTES; }; hmac[0]=0; if(stun_calculate_hmac(g_uname, strlen((char*)g_uname), (u08bits*)g_auth_secret, strlen(g_auth_secret), hmac, &hmac_len, shatype)>=0) { size_t pwd_length = 0; char *pwd = base64_encode(hmac,hmac_len,&pwd_length); if(pwd) { if(pwd_length>0) { ns_bcopy(pwd,g_upwd,pwd_length); g_upwd[pwd_length]=0; } } free(pwd); } } } if(is_TCP_relay()) { dont_fragment = 0; no_rtcp = 1; c2c = 1; use_tcp = 1; do_not_use_channel = 1; } if(port == 0) { if(use_secure) port = DEFAULT_STUN_TLS_PORT; else port = DEFAULT_STUN_PORT; } if (clmessage_length < (int) sizeof(message_info)) clmessage_length = (int) sizeof(message_info); const int max_header = 100; if(clmessage_length > (int)(STUN_BUFFER_SIZE-max_header)) { fprintf(stderr,"Message length was corrected to %d\n",(STUN_BUFFER_SIZE-max_header)); clmessage_length = (int)(STUN_BUFFER_SIZE-max_header); } if (optind >= argc) { fprintf(stderr, "%s\n", Usage); exit(-1); } if (!c2c) { if (make_ioa_addr((const u08bits*) peer_address, peer_port, &peer_addr) < 0) return -1; if(peer_addr.ss.sa_family == AF_INET6) default_address_family = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; } /* SSL Init ==>> */ if(use_secure) { SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); const char *csuite = "ALL"; //"AES256-SHA" "DH" if(use_null_cipher) csuite = "eNULL"; else if(cipher_suite[0]) csuite=cipher_suite; if(use_tcp) { root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(SSLv23_client_method()); SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); root_tls_ctx_num++; root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(SSLv3_client_method()); SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); root_tls_ctx_num++; root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLSv1_client_method()); SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); root_tls_ctx_num++; #if defined(SSL_TXT_TLSV1_1) root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLSv1_1_client_method()); SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); root_tls_ctx_num++; #if defined(SSL_TXT_TLSV1_2) root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLSv1_2_client_method()); SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); root_tls_ctx_num++; #endif #endif } else { #if defined(TURN_NO_DTLS) fprintf(stderr,"ERROR: DTLS is not supported.\n"); exit(-1); #else if(OPENSSL_VERSION_NUMBER < 0x10000000L) { TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: OpenSSL version is rather old, DTLS may not be working correctly.\n"); } root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(DTLSv1_client_method()); SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); root_tls_ctx_num++; #endif } int sslind = 0; for(sslind = 0; sslind<root_tls_ctx_num; sslind++) { if(cert_file[0]) { if (!SSL_CTX_use_certificate_chain_file(root_tls_ctx[sslind], cert_file)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nERROR: no certificate found!\n"); exit(-1); } } if (!SSL_CTX_use_PrivateKey_file(root_tls_ctx[sslind], pkey_file, SSL_FILETYPE_PEM)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nERROR: no private key found!\n"); exit(-1); } if(cert_file[0]) { if (!SSL_CTX_check_private_key(root_tls_ctx[sslind])) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nERROR: invalid private key!\n"); exit(-1); } } if (ca_cert_file[0]) { if (!SSL_CTX_load_verify_locations(root_tls_ctx[sslind], ca_cert_file, NULL )) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: cannot load CA from file: %s\n", ca_cert_file); } /* Set to require peer (client) certificate verification */ SSL_CTX_set_verify(root_tls_ctx[sslind], SSL_VERIFY_PEER, NULL ); /* Set the verification depth to 9 */ SSL_CTX_set_verify_depth(root_tls_ctx[sslind], 9); } else { SSL_CTX_set_verify(root_tls_ctx[sslind], SSL_VERIFY_NONE, NULL ); } if(!use_tcp) SSL_CTX_set_read_ahead(root_tls_ctx[sslind], 1); } } start_mclient(argv[optind], port, client_ifname, local_addr, messagenumber, mclient); return 0; }
static int init_server(dtls_listener_relay_server_type* server, const char* ifname, const char *local_address, int port, int verbose, ioa_engine_handle e, turn_turnserver *ts, int report_creation, ioa_engine_new_connection_event_handler send_socket) { if(!server) return -1; #if DTLS_SUPPORTED server->dtls_ctx = e->dtls_ctx; #if DTLSv1_2_SUPPORTED server->dtls_ctx_v1_2 = e->dtls_ctx_v1_2; #endif #endif server->ts = ts; server->connect_cb = send_socket; if(ifname) STRCPY(server->ifname,ifname); if(make_ioa_addr((const u08bits*)local_address, port, &server->addr)<0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot create a DTLS/UDP listener for address: %s\n",local_address); return -1; } server->slen0 = get_ioa_addr_len(&(server->addr)); server->verbose=verbose; server->e = e; #if DTLS_SUPPORTED if(server->dtls_ctx) { #if defined(REQUEST_CLIENT_CERT) /* If client has to authenticate, then */ SSL_CTX_set_verify(server->dtls_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, dtls_verify_callback); #endif SSL_CTX_set_read_ahead(server->dtls_ctx, 1); SSL_CTX_set_cookie_generate_cb(server->dtls_ctx, generate_cookie); SSL_CTX_set_cookie_verify_cb(server->dtls_ctx, verify_cookie); } #if DTLSv1_2_SUPPORTED if(server->dtls_ctx_v1_2) { #if defined(REQUEST_CLIENT_CERT) /* If client has to authenticate, then */ SSL_CTX_set_verify(server->dtls_ctx_v1_2, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, dtls_verify_callback); #endif SSL_CTX_set_read_ahead(server->dtls_ctx_v1_2, 1); SSL_CTX_set_cookie_generate_cb(server->dtls_ctx_v1_2, generate_cookie); SSL_CTX_set_cookie_verify_cb(server->dtls_ctx_v1_2, verify_cookie); } #endif #endif return create_server_socket(server, report_creation); }
int start_connection(uint16_t clnet_remote_port0, const char *remote_address0, const unsigned char* ifname, const char *local_address, int verbose, app_ur_conn_info *clnet_info_probe, app_ur_conn_info *clnet_info, uint16_t *chn, app_ur_conn_info *clnet_info_rtcp, uint16_t *chn_rtcp) { ioa_addr relay_addr; ioa_addr relay_addr_rtcp; ioa_addr peer_addr_rtcp; addr_cpy(&peer_addr_rtcp,&peer_addr); addr_set_port(&peer_addr_rtcp,addr_get_port(&peer_addr_rtcp)+1); /* Probe: */ if (clnet_connect(clnet_remote_port0, remote_address0, ifname, local_address, verbose, clnet_info_probe) < 0) { exit(-1); } uint16_t clnet_remote_port = clnet_remote_port0; char remote_address[1025]; STRCPY(remote_address,remote_address0); clnet_allocate(verbose, clnet_info_probe, &relay_addr, default_address_family, remote_address, &clnet_remote_port); /* Real: */ *chn = 0; if(chn_rtcp) *chn_rtcp=0; if (clnet_connect(clnet_remote_port, remote_address, ifname, local_address, verbose, clnet_info) < 0) { exit(-1); } if(!no_rtcp) { if (clnet_connect(clnet_remote_port, remote_address, ifname, local_address, verbose, clnet_info_rtcp) < 0) { exit(-1); } } int af = default_address_family ? default_address_family : get_allocate_address_family(&peer_addr); if (clnet_allocate(verbose, clnet_info, &relay_addr, af, NULL,NULL) < 0) { exit(-1); } if(rare_event()) return 0; if(!no_rtcp) { af = default_address_family ? default_address_family : get_allocate_address_family(&peer_addr_rtcp); if (clnet_allocate(verbose, clnet_info_rtcp, &relay_addr_rtcp, af,NULL,NULL) < 0) { exit(-1); } if(rare_event()) return 0; } if (!dos) { if (!do_not_use_channel) { /* These multiple "channel bind" requests are here only because * we are playing with the TURN server trying to screw it */ if (turn_channel_bind(verbose, chn, clnet_info, &peer_addr_rtcp) < 0) { exit(-1); } if(rare_event()) return 0; if (turn_channel_bind(verbose, chn, clnet_info, &peer_addr_rtcp) < 0) { exit(-1); } if(rare_event()) return 0; *chn = 0; if (turn_channel_bind(verbose, chn, clnet_info, &peer_addr) < 0) { exit(-1); } if(rare_event()) return 0; if (turn_channel_bind(verbose, chn, clnet_info, &peer_addr) < 0) { exit(-1); } if(rare_event()) return 0; if(extra_requests) { const char *sarbaddr = "164.156.178.190"; if(random() % 2 == 0) sarbaddr = "2001::172"; ioa_addr arbaddr; make_ioa_addr((const u08bits*)sarbaddr, 333, &arbaddr); int i; int maxi = (unsigned short)random() % EXTRA_CREATE_PERMS; for(i=0;i<maxi;i++) { u16bits chni=0; int port = (unsigned short)random(); if(port<1024) port += 1024; addr_set_port(&arbaddr, port); u08bits *u=(u08bits*)&(arbaddr.s4.sin_addr); u[(unsigned short)random()%4] = u[(unsigned short)random()%4] + 1; //char sss[128]; //addr_to_string(&arbaddr,(u08bits*)sss); //printf("%s: 111.111: %s\n",__FUNCTION__,sss); turn_channel_bind(verbose, &chni, clnet_info, &arbaddr); } } if (!no_rtcp) { if (turn_channel_bind(verbose, chn_rtcp, clnet_info_rtcp, &peer_addr_rtcp) < 0) { exit(-1); } } if(rare_event()) return 0; if(extra_requests) { const char *sarbaddr = "64.56.78.90"; if(random() % 2 == 0) sarbaddr = "2001::172"; ioa_addr arbaddr[EXTRA_CREATE_PERMS]; make_ioa_addr((const u08bits*)sarbaddr, 333, &arbaddr[0]); int i; int maxi = (unsigned short)random() % EXTRA_CREATE_PERMS; for(i=0;i<maxi;i++) { if(i>0) addr_cpy(&arbaddr[i],&arbaddr[0]); addr_set_port(&arbaddr[i], (unsigned short)random()); u08bits *u=(u08bits*)&(arbaddr[i].s4.sin_addr); u[(unsigned short)random()%4] = u[(unsigned short)random()%4] + 1; //char sss[128]; //addr_to_string(&arbaddr[i],(u08bits*)sss); //printf("%s: 111.111: %s\n",__FUNCTION__,sss); } turn_create_permission(verbose, clnet_info, arbaddr, maxi); } } else { int before=(random()%2 == 0); if(before) { if (turn_create_permission(verbose, clnet_info, &peer_addr, 1) < 0) { exit(-1); } if(rare_event()) return 0; if (turn_create_permission(verbose, clnet_info, &peer_addr_rtcp, 1) < 0) { exit(-1); } if(rare_event()) return 0; } if(extra_requests) { const char *sarbaddr = "64.56.78.90"; if(random() % 2 == 0) sarbaddr = "2001::172"; ioa_addr arbaddr[EXTRA_CREATE_PERMS]; make_ioa_addr((const u08bits*)sarbaddr, 333, &arbaddr[0]); int i; int maxi = (unsigned short)random() % EXTRA_CREATE_PERMS; for(i=0;i<maxi;i++) { if(i>0) addr_cpy(&arbaddr[i],&arbaddr[0]); addr_set_port(&arbaddr[i], (unsigned short)random()); u08bits *u=(u08bits*)&(arbaddr[i].s4.sin_addr); u[(unsigned short)random()%4] = u[(unsigned short)random()%4] + 1; //char sss[128]; //addr_to_string(&arbaddr,(u08bits*)sss); //printf("%s: 111.111: %s\n",__FUNCTION__,sss); } turn_create_permission(verbose, clnet_info, arbaddr, maxi); } if(!before) { if (turn_create_permission(verbose, clnet_info, &peer_addr, 1) < 0) { exit(-1); } if(rare_event()) return 0; if (turn_create_permission(verbose, clnet_info, &peer_addr_rtcp, 1) < 0) { exit(-1); } if(rare_event()) return 0; } if (!no_rtcp) { if (turn_create_permission(verbose, clnet_info_rtcp, &peer_addr_rtcp, 1) < 0) { exit(-1); } if(rare_event()) return 0; if (turn_create_permission(verbose, clnet_info_rtcp, &peer_addr, 1) < 0) { exit(-1); } if(rare_event()) return 0; } } } addr_cpy(&(clnet_info->peer_addr), &peer_addr); if(!no_rtcp) addr_cpy(&(clnet_info_rtcp->peer_addr), &peer_addr_rtcp); return 0; }
static int clnet_connect(uint16_t clnet_remote_port, const char *remote_address, const unsigned char* ifname, const char *local_address, int verbose, app_ur_conn_info *clnet_info) { ioa_addr local_addr; evutil_socket_t clnet_fd; int connect_err; int connect_cycle = 0; ioa_addr remote_addr; start_socket: clnet_fd = -1; connect_err = 0; ns_bzero(&remote_addr, sizeof(ioa_addr)); if (make_ioa_addr((const u08bits*) remote_address, clnet_remote_port, &remote_addr) < 0) return -1; ns_bzero(&local_addr, sizeof(ioa_addr)); clnet_fd = socket(remote_addr.ss.sa_family, use_sctp ? SCTP_CLIENT_STREAM_SOCKET_TYPE : (use_tcp ? CLIENT_STREAM_SOCKET_TYPE : CLIENT_DGRAM_SOCKET_TYPE), use_sctp ? SCTP_CLIENT_STREAM_SOCKET_PROTOCOL : (use_tcp ? CLIENT_STREAM_SOCKET_PROTOCOL : CLIENT_DGRAM_SOCKET_PROTOCOL)); if (clnet_fd < 0) { perror("socket"); exit(-1); } if (sock_bind_to_device(clnet_fd, ifname) < 0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Cannot bind client socket to device %s\n", ifname); } set_sock_buf_size(clnet_fd, UR_CLIENT_SOCK_BUF_SIZE); set_raw_socket_tos(clnet_fd, remote_addr.ss.sa_family, 0x22); set_raw_socket_ttl(clnet_fd, remote_addr.ss.sa_family, 47); if(clnet_info->is_peer && (*local_address==0)) { if(remote_addr.ss.sa_family == AF_INET6) { if (make_ioa_addr((const u08bits*) "::1", 0, &local_addr) < 0) { return -1; } } else { if (make_ioa_addr((const u08bits*) "127.0.0.1", 0, &local_addr) < 0) { return -1; } } addr_bind(clnet_fd, &local_addr, 0, 1, get_socket_type()); } else if (strlen(local_address) > 0) { if (make_ioa_addr((const u08bits*) local_address, 0, &local_addr) < 0) return -1; addr_bind(clnet_fd, &local_addr,0,1,get_socket_type()); } if(clnet_info->is_peer) { ; } else if(socket_connect(clnet_fd, &remote_addr, &connect_err)>0) goto start_socket; if (clnet_info) { addr_cpy(&(clnet_info->remote_addr), &remote_addr); addr_cpy(&(clnet_info->local_addr), &local_addr); clnet_info->fd = clnet_fd; addr_get_from_sock(clnet_fd, &(clnet_info->local_addr)); STRCPY(clnet_info->lsaddr,local_address); STRCPY(clnet_info->rsaddr,remote_address); STRCPY(clnet_info->ifname,(const char*)ifname); } if (use_secure) { int try_again = 0; clnet_info->ssl = tls_connect(clnet_info->fd, &remote_addr,&try_again,connect_cycle++); if (!clnet_info->ssl) { if(try_again) { goto start_socket; } TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: cannot SSL connect to remote addr\n", __FUNCTION__); exit(-1); } } if(verbose && clnet_info) { addr_debug_print(verbose, &(clnet_info->local_addr), "Connected from"); addr_debug_print(verbose, &remote_addr, "Connected to"); } if(!dos) usleep(500); return 0; }
int start_c2c_connection(uint16_t clnet_remote_port0, const char *remote_address0, const unsigned char* ifname, const char *local_address, int verbose, app_ur_conn_info *clnet_info_probe, app_ur_conn_info *clnet_info1, uint16_t *chn1, app_ur_conn_info *clnet_info1_rtcp, uint16_t *chn1_rtcp, app_ur_conn_info *clnet_info2, uint16_t *chn2, app_ur_conn_info *clnet_info2_rtcp, uint16_t *chn2_rtcp) { ioa_addr relay_addr1; ioa_addr relay_addr1_rtcp; ioa_addr relay_addr2; ioa_addr relay_addr2_rtcp; *chn1 = 0; *chn2 = 0; if(chn1_rtcp) *chn1_rtcp=0; if(chn2_rtcp) *chn2_rtcp=0; /* Probe: */ if (clnet_connect(clnet_remote_port0, remote_address0, ifname, local_address, verbose, clnet_info_probe) < 0) { exit(-1); } uint16_t clnet_remote_port = clnet_remote_port0; char remote_address[1025]; STRCPY(remote_address,remote_address0); clnet_allocate(verbose, clnet_info_probe, &relay_addr1, default_address_family, remote_address, &clnet_remote_port); if(rare_event()) return 0; /* Real: */ if (clnet_connect(clnet_remote_port, remote_address, ifname, local_address, verbose, clnet_info1) < 0) { exit(-1); } if(!no_rtcp) if (clnet_connect(clnet_remote_port, remote_address, ifname, local_address, verbose, clnet_info1_rtcp) < 0) { exit(-1); } if(passive_tcp) clnet_info2->is_peer = 1; if (clnet_connect(clnet_remote_port, remote_address, ifname, local_address, verbose, clnet_info2) < 0) { exit(-1); } if(!no_rtcp) if (clnet_connect(clnet_remote_port, remote_address, ifname, local_address, verbose, clnet_info2_rtcp) < 0) { exit(-1); } if(!no_rtcp) { if (clnet_allocate(verbose, clnet_info1, &relay_addr1, default_address_family,NULL,NULL) < 0) { exit(-1); } if(rare_event()) return 0; if (clnet_allocate(verbose, clnet_info1_rtcp, &relay_addr1_rtcp, default_address_family,NULL,NULL) < 0) { exit(-1); } if(rare_event()) return 0; if (clnet_allocate(verbose, clnet_info2, &relay_addr2, default_address_family,NULL,NULL) < 0) { exit(-1); } if(rare_event()) return 0; if (clnet_allocate(verbose, clnet_info2_rtcp, &relay_addr2_rtcp, default_address_family,NULL,NULL) < 0) { exit(-1); } if(rare_event()) return 0; } else { if (clnet_allocate(verbose, clnet_info1, &relay_addr1, default_address_family,NULL,NULL) < 0) { exit(-1); } if(rare_event()) return 0; if(!(clnet_info2->is_peer)) { if (clnet_allocate(verbose, clnet_info2, &relay_addr2, default_address_family,NULL,NULL) < 0) { exit(-1); } if(rare_event()) return 0; } else { addr_cpy(&(clnet_info2->remote_addr),&relay_addr1); addr_cpy(&relay_addr2,&(clnet_info2->local_addr)); } } if (!do_not_use_channel) { if (turn_channel_bind(verbose, chn1, clnet_info1, &relay_addr2) < 0) { exit(-1); } if(extra_requests) { const char *sarbaddr = "164.156.178.190"; if(random() % 2 == 0) sarbaddr = "2001::172"; ioa_addr arbaddr; make_ioa_addr((const u08bits*)sarbaddr, 333, &arbaddr); int i; int maxi = (unsigned short)random() % EXTRA_CREATE_PERMS; for(i=0;i<maxi;i++) { u16bits chni=0; int port = (unsigned short)random(); if(port<1024) port += 1024; addr_set_port(&arbaddr, port); u08bits *u=(u08bits*)&(arbaddr.s4.sin_addr); u[(unsigned short)random()%4] = u[(unsigned short)random()%4] + 1; //char sss[128]; //addr_to_string(&arbaddr,(u08bits*)sss); //printf("%s: 111.111: %s\n",__FUNCTION__,sss); turn_channel_bind(verbose, &chni, clnet_info1, &arbaddr); } } if(rare_event()) return 0; if(extra_requests) { const char *sarbaddr = "64.56.78.90"; if(random() % 2 == 0) sarbaddr = "2001::172"; ioa_addr arbaddr[EXTRA_CREATE_PERMS]; make_ioa_addr((const u08bits*)sarbaddr, 333, &arbaddr[0]); int i; int maxi = (unsigned short)random() % EXTRA_CREATE_PERMS; for(i=0;i<maxi;i++) { if(i>0) addr_cpy(&arbaddr[i],&arbaddr[0]); addr_set_port(&arbaddr[i], (unsigned short)random()); u08bits *u=(u08bits*)&(arbaddr[i].s4.sin_addr); u[(unsigned short)random()%4] = u[(unsigned short)random()%4] + 1; //char sss[128]; //addr_to_string(&arbaddr[i],(u08bits*)sss); //printf("%s: 111.111: %s\n",__FUNCTION__,sss); } turn_create_permission(verbose, clnet_info1, arbaddr, maxi); } if(!no_rtcp) if (turn_channel_bind(verbose, chn1_rtcp, clnet_info1_rtcp, &relay_addr2_rtcp) < 0) { exit(-1); } if(rare_event()) return 0; if (turn_channel_bind(verbose, chn2, clnet_info2, &relay_addr1) < 0) { exit(-1); } if(rare_event()) return 0; if(!no_rtcp) if (turn_channel_bind(verbose, chn2_rtcp, clnet_info2_rtcp, &relay_addr1_rtcp) < 0) { exit(-1); } if(rare_event()) return 0; } else { if (turn_create_permission(verbose, clnet_info1, &relay_addr2, 1) < 0) { exit(-1); } if(extra_requests) { const char *sarbaddr = "64.56.78.90"; if(random() % 2 == 0) sarbaddr = "2001::172"; ioa_addr arbaddr; make_ioa_addr((const u08bits*)sarbaddr, 333, &arbaddr); int i; int maxi = (unsigned short)random() % EXTRA_CREATE_PERMS; for(i=0;i<maxi;i++) { addr_set_port(&arbaddr, (unsigned short)random()); u08bits *u=(u08bits*)&(arbaddr.s4.sin_addr); u[(unsigned short)random()%4] = u[(unsigned short)random()%4] + 1; //char sss[128]; //addr_to_string(&arbaddr,(u08bits*)sss); //printf("%s: 111.111: %s\n",__FUNCTION__,sss); turn_create_permission(verbose, clnet_info1, &arbaddr, 1); } } if(rare_event()) return 0; if (!no_rtcp) if (turn_create_permission(verbose, clnet_info1_rtcp, &relay_addr2_rtcp, 1) < 0) { exit(-1); } if(rare_event()) return 0; if(!(clnet_info2->is_peer)) { if (turn_create_permission(verbose, clnet_info2, &relay_addr1, 1) < 0) { exit(-1); } if(rare_event()) return 0; } if (!no_rtcp) if (turn_create_permission(verbose, clnet_info2_rtcp, &relay_addr1_rtcp, 1) < 0) { exit(-1); } if(rare_event()) return 0; } addr_cpy(&(clnet_info1->peer_addr), &relay_addr2); if(!no_rtcp) addr_cpy(&(clnet_info1_rtcp->peer_addr), &relay_addr2_rtcp); addr_cpy(&(clnet_info2->peer_addr), &relay_addr1); if(!no_rtcp) addr_cpy(&(clnet_info2_rtcp->peer_addr), &relay_addr1_rtcp); return 0; }
int main(int argc, char **argv) { int port = 0; int messagenumber = 5; char local_addr[256]; char c; int mclient = 1; unsigned char ifname[1025] = "\0"; char peer_address[129] = "\0"; int peer_port = PEER_DEFAULT_PORT; set_execdir(); srandom((unsigned int) time(NULL)); memset(local_addr, 0, sizeof(local_addr)); while ((c = getopt(argc, argv, "d:p:l:n:L:m:e:r:u:w:i:k:z:vsyhcxgtS")) != -1) { switch (c){ case 'z': RTP_PACKET_INTERVAL = atoi(optarg); break; case 'u': STRCPY(g_uname, optarg); break; case 'w': STRCPY(g_upwd, optarg); break; case 'g': dont_fragment = 1; break; case 'd': STRCPY(ifname, optarg); break; case 'x': default_address_family = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; break; case 'l': clmessage_length = atoi(optarg); break; case 's': use_send_method = 1; break; case 'n': messagenumber = atoi(optarg); break; case 'p': port = atoi(optarg); break; case 'L': STRCPY(local_addr, optarg); break; case 'e': STRCPY(peer_address, optarg); break; case 'r': peer_port = atoi(optarg); break; case 'v': clnet_verbose = 1; break; case 'h': hang_on = 1; break; case 'c': no_rtcp = 1; break; case 'm': mclient = atoi(optarg); break; case 'y': c2c = 1; break; case 't': use_tcp = 1; break; case 'S': use_secure = 1; break; case 'i': { char* fn = find_config_file(optarg,1); if(!fn) { fprintf(stderr,"ERROR: file %s not found\n",optarg); exit(-1); } strcpy(cert_file,fn); free(fn); break; } case 'k': { char* fn = find_config_file(optarg,1); if(!fn) { fprintf(stderr,"ERROR: file %s not found\n",optarg); exit(-1); } STRCPY(pkey_file,fn); free(fn); break; } default: fprintf(stderr, "%s\n", Usage); exit(1); } } if(port == 0) { if(use_secure) port = DEFAULT_STUN_TLS_PORT; else port = DEFAULT_STUN_PORT; } if (clmessage_length < (int) sizeof(message_info)) clmessage_length = (int) sizeof(message_info); if (optind >= argc) { fprintf(stderr, "%s\n", Usage); exit(-1); } if (!c2c) { if (make_ioa_addr((const u08bits*) peer_address, peer_port, &peer_addr) < 0) return -1; } /* SSL Init ==>> */ if(use_secure) { SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); if(use_tcp) { root_tls_ctx = SSL_CTX_new(TLSv1_client_method()); } else { #if !defined(BIO_CTRL_DGRAM_QUERY_MTU) fprintf(stderr,"ERROR: DTLS is not supported.\n"); exit(-1); #else if(OPENSSL_VERSION_NUMBER < 0x10000000L) { TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: OpenSSL version is rather old, DTLS may not be working correctly.\n"); } root_tls_ctx = SSL_CTX_new(DTLSv1_client_method()); #endif } SSL_CTX_set_cipher_list(root_tls_ctx, "DEFAULT"); if (!SSL_CTX_use_certificate_file(root_tls_ctx, cert_file, SSL_FILETYPE_PEM)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nERROR: no certificate found!\n"); exit(-1); } if (!SSL_CTX_use_PrivateKey_file(root_tls_ctx, pkey_file, SSL_FILETYPE_PEM)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nERROR: no private key found!\n"); exit(-1); } if (!SSL_CTX_check_private_key(root_tls_ctx)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nERROR: invalid private key!\n"); exit(-1); } SSL_CTX_set_verify_depth(root_tls_ctx, 2); SSL_CTX_set_read_ahead(root_tls_ctx, 1); } start_mclient(argv[optind], port, ifname, local_addr, messagenumber, mclient); return 0; }
int main(int argc, const char **argv) { int res = -1; UNUSED_ARG(argc); UNUSED_ARG(argv); if(argc>1) print_extra = 1; set_logfile("stdout"); set_system_parameters(0); { const unsigned char reqstc[] = "\x00\x01\x00\x58" "\x21\x12\xa4\x42" "\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" "\x80\x22\x00\x10" "STUN test client" "\x00\x24\x00\x04" "\x6e\x00\x01\xff" "\x80\x29\x00\x08" "\x93\x2f\xf9\xb1\x51\x26\x3b\x36" "\x00\x06\x00\x09" "\x65\x76\x74\x6a\x3a\x68\x36\x76\x59\x20\x20\x20" "\x00\x08\x00\x14" "\x9a\xea\xa7\x0c\xbf\xd8\xcb\x56\x78\x1e\xf2\xb5" "\xb2\xd3\xf2\x49\xc1\xb5\x71\xa2" "\x80\x28\x00\x04" "\xe5\x7a\x3b\xcf"; u08bits buf[sizeof(reqstc)]; memcpy(buf, reqstc, sizeof(reqstc)); {//fingerprintfs etc res = stun_is_command_message_full_check_str(buf, sizeof(reqstc) - 1, 1, NULL); printf("RFC 5769 message fingerprint test(0) result: "); if (res) { printf("success\n"); } else if (res == 0) { printf("failure on fingerprint(0) check\n"); exit(-1); } } {//short-term credentials u08bits uname[33]; u08bits realm[33]; u08bits upwd[33]; strcpy((char*) upwd, "VOkJxbRl1RmTxUk/WvJxBt"); res = stun_check_message_integrity_str(TURN_CREDENTIALS_SHORT_TERM, buf, sizeof(reqstc) - 1, uname, realm, upwd, shatype); printf("RFC 5769 simple request short-term credentials and integrity test result: "); if (res > 0) { printf("success\n"); } else if (res == 0) { printf("failure on integrity check\n"); exit(-1); } else { printf("failure on message structure check\n"); exit(-1); } } {//negative fingerprint buf[27] = 23; res = stun_is_command_message_full_check_str(buf, sizeof(reqstc) - 1, 1, NULL); printf("RFC 5769 NEGATIVE fingerprint test(0) result: "); if (!res) { printf("success\n"); } else if (res == 0) { printf("failure on NEGATIVE fingerprint check\n"); exit(-1); } } } { const unsigned char reqltc[] = "\x00\x01\x00\x60" "\x21\x12\xa4\x42" "\x78\xad\x34\x33\xc6\xad\x72\xc0\x29\xda\x41\x2e" "\x00\x06\x00\x12" "\xe3\x83\x9e\xe3\x83\x88\xe3\x83\xaa\xe3\x83\x83" "\xe3\x82\xaf\xe3\x82\xb9\x00\x00" "\x00\x15\x00\x1c" "\x66\x2f\x2f\x34\x39\x39\x6b\x39\x35\x34\x64\x36" "\x4f\x4c\x33\x34\x6f\x4c\x39\x46\x53\x54\x76\x79" "\x36\x34\x73\x41" "\x00\x14\x00\x0b" "\x65\x78\x61\x6d\x70\x6c\x65\x2e\x6f\x72\x67\x00" "\x00\x08\x00\x14" "\xf6\x70\x24\x65\x6d\xd6\x4a\x3e\x02\xb8\xe0\x71" "\x2e\x85\xc9\xa2\x8c\xa8\x96\x66"; u08bits user[] = "\xe3\x83\x9e\xe3\x83\x88\xe3\x83\xaa\xe3\x83\x83" "\xe3\x82\xaf\xe3\x82\xb9"; u08bits realm[33]; u08bits nonce[29]; u08bits upwd[33]; u08bits buf[sizeof(reqltc)]; memcpy(buf, reqltc, sizeof(reqltc)); u08bits uname[sizeof(user)]; memcpy(uname, user, sizeof(user)); strcpy((char*) realm, "example.org"); strcpy((char*) upwd, "TheMatrIX"); strcpy((char*)nonce,"f//499k954d6OL34oL9FSTvy64sA"); res = stun_check_message_integrity_str(TURN_CREDENTIALS_LONG_TERM, buf, sizeof(reqltc) - 1, uname, realm, upwd, shatype); printf("RFC 5769 message structure, long-term credentials and integrity test result: "); if (res > 0) { printf("success\n"); } else if (res == 0) { printf("failure on integrity check\n"); exit(-1); } else { printf("failure on message structure check\n"); exit(-1); } { //encoding test printf("RFC 5769 message encoding test result: "); size_t len = 0; u16bits message_type = STUN_METHOD_BINDING; stun_tid tid; u16bits *buf16 = (u16bits*)buf; u32bits *buf32 = (u32bits*)buf; memcpy(tid.tsx_id,"\x78\xad\x34\x33\xc6\xad\x72\xc0\x29\xda\x41\x2e",12); stun_init_buffer_str(buf,&len); message_type &= (u16bits)(0x3FFF); buf16[0]=nswap16(message_type); buf16[1]=0; buf32[1]=nswap32(STUN_MAGIC_COOKIE); stun_tid_message_cpy(buf, &tid); stun_attr_add_integrity_by_user_str(buf, &len, uname, realm, upwd, nonce, shatype); if(len != (sizeof(reqltc)-1)) { printf("failure: length %d, must be %d\n",(int)len,(int)(sizeof(reqltc)-1)); exit(-1); } if(memcmp(buf,reqltc,len)) { printf("failure: wrong message content\n"); { int lines = 29; int line = 0; int col = 0; int cols = 4; for(line = 0;line<lines;line++) { for(col = 0; col<cols; col++) { u08bits c = buf[line*4+col]; printf(" %2x",(int)c); } printf("\n"); } } exit(-1); } printf("success\n"); } //Negative test: buf[32] = 10; res = stun_check_message_integrity_str(TURN_CREDENTIALS_LONG_TERM, buf, sizeof(reqltc) - 1, uname, realm, upwd, shatype); printf("RFC 5769 NEGATIVE long-term credentials test result: "); if (res == 0) { printf("success\n"); } else { printf("failure on NEGATIVE long-term credentials check\n"); exit(-1); } } { const unsigned char respv4[] = "\x01\x01\x00\x3c" "\x21\x12\xa4\x42" "\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" "\x80\x22\x00\x0b" "\x74\x65\x73\x74\x20\x76\x65\x63\x74\x6f\x72\x20" "\x00\x20\x00\x08" "\x00\x01\xa1\x47\xe1\x12\xa6\x43" "\x00\x08\x00\x14" "\x2b\x91\xf5\x99\xfd\x9e\x90\xc3\x8c\x74\x89\xf9" "\x2a\xf9\xba\x53\xf0\x6b\xe7\xd7" "\x80\x28\x00\x04" "\xc0\x7d\x4c\x96"; u08bits buf[sizeof(respv4)]; memcpy(buf, respv4, sizeof(respv4)); {//fingerprintfs etc res = stun_is_command_message_full_check_str(buf, sizeof(respv4) - 1, 1, NULL); printf("RFC 5769 message fingerprint test(1) result: "); if (res) { printf("success\n"); } else if (res == 0) { printf("failure on fingerprint(1) check\n"); exit(-1); } } {//short-term credentials u08bits uname[33]; u08bits realm[33]; u08bits upwd[33]; strcpy((char*) upwd, "VOkJxbRl1RmTxUk/WvJxBt"); res = stun_check_message_integrity_str(TURN_CREDENTIALS_SHORT_TERM, buf, sizeof(respv4) - 1, uname, realm, upwd, shatype); printf("RFC 5769 IPv4 response short-term credentials and integrity test result: "); if (res > 0) { printf("success\n"); } else if (res == 0) { printf("failure on integrity check\n"); exit(-1); } else { printf("failure on message structure check\n"); exit(-1); } } {//negative fingerprint buf[27] = 23; res = stun_is_command_message_full_check_str(buf, sizeof(respv4) - 1, 1, NULL); printf("RFC 5769 NEGATIVE fingerprint test(1) result: "); if (!res) { printf("success\n"); } else if (res == 0) { printf("failure on NEGATIVE fingerprint check\n"); exit(-1); } } {//IPv4 addr ioa_addr addr4; ioa_addr addr4_test; printf("RFC 5769 IPv4 encoding result: "); res = stun_attr_get_first_addr_str(buf, sizeof(respv4)-1, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &addr4, NULL); if(res < 0) { printf("failure on message structure check\n"); exit(-1); } make_ioa_addr((const u08bits*)"192.0.2.1", 32853, &addr4_test); if(addr_eq(&addr4,&addr4_test)) { printf("success\n"); } else { printf("failure on IPv4 deconding check\n"); exit(-1); } } } { const unsigned char respv6[] = "\x01\x01\x00\x48" "\x21\x12\xa4\x42" "\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" "\x80\x22\x00\x0b" "\x74\x65\x73\x74\x20\x76\x65\x63\x74\x6f\x72\x20" "\x00\x20\x00\x14" "\x00\x02\xa1\x47" "\x01\x13\xa9\xfa\xa5\xd3\xf1\x79" "\xbc\x25\xf4\xb5\xbe\xd2\xb9\xd9" "\x00\x08\x00\x14" "\xa3\x82\x95\x4e\x4b\xe6\x7b\xf1\x17\x84\xc9\x7c" "\x82\x92\xc2\x75\xbf\xe3\xed\x41" "\x80\x28\x00\x04" "\xc8\xfb\x0b\x4c"; u08bits buf[sizeof(respv6)]; { //decoding test memcpy(buf, respv6, sizeof(respv6)); res = stun_is_command_message_full_check_str(buf, sizeof(respv6) - 1, 1, NULL); printf("RFC 5769 message fingerprint test(2) result: "); if (res) { printf("success\n"); } else if (res == 0) { printf("failure on fingerprint(2) check\n"); exit(-1); } } {//short-term credentials test u08bits uname[33]; u08bits realm[33]; u08bits upwd[33]; strcpy((char*) upwd, "VOkJxbRl1RmTxUk/WvJxBt"); res = stun_check_message_integrity_str(TURN_CREDENTIALS_SHORT_TERM, buf, sizeof(respv6) - 1, uname, realm, upwd, shatype); printf("RFC 5769 IPv6 response short-term credentials and integrity test result: "); if (res > 0) { printf("success\n"); } else if (res == 0) { printf("failure on integrity check\n"); exit(-1); } else { printf("failure on message structure check\n"); exit(-1); } } {//negative decoding test buf[27] = 23; res = stun_is_command_message_full_check_str(buf, sizeof(respv6) - 1, 1, NULL); printf("RFC 5769 NEGATIVE fingerprint test(2) result: "); if (!res) { printf("success\n"); } else if (res == 0) { printf("failure on NEGATIVE fingerprint check\n"); exit(-1); } } {//IPv6 deconding test ioa_addr addr6; ioa_addr addr6_test; printf("RFC 5769 IPv6 encoding result: "); res = stun_attr_get_first_addr_str(buf, sizeof(respv6) - 1, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &addr6, NULL); if (res < 0) { printf("failure on message structure check\n"); exit(-1); } make_ioa_addr((const u08bits*) "2001:db8:1234:5678:11:2233:4455:6677", 32853, &addr6_test); if (addr_eq(&addr6, &addr6_test)) { printf("success\n"); } else { printf("failure on IPv6 deconding check\n"); exit(-1); } } } { if(check_oauth()<0) exit(-1); } return 0; }