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);
}
Exemple #3
0
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);
}
Exemple #5
0
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;
}
Exemple #6
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);
}
Exemple #7
0
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;
}
Exemple #8
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;
}
Exemple #9
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;
}
Exemple #10
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;
}
Exemple #11
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;
}