static int create_server_listener(tls_listener_relay_server_type* server) {

  FUNCSTART;

  if(!server) return -1;

  evutil_socket_t tls_listen_fd = -1;

  tls_listen_fd = socket(server->addr.ss.ss_family, SOCK_STREAM, 0);
  if (tls_listen_fd < 0) {
      perror("socket");
      return -1;
  }

  if(sock_bind_to_device(tls_listen_fd, (unsigned char*)server->ifname)<0) {
    TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind listener socket to device %s\n",server->ifname);
  }

  if(addr_bind(tls_listen_fd,&server->addr)<0) {
  	  perror("Cannot bind local socket to addr");
  	  char saddr[129];
  	  addr_to_string(&server->addr,(u08bits*)saddr);
  	  TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind TCP/TLS listener socket to addr %s\n",saddr);
  	  socket_closesocket(tls_listen_fd);
  	  return -1;
  }

  socket_tcp_set_keepalive(tls_listen_fd);

  socket_set_nonblocking(tls_listen_fd);

  server->l = evconnlistener_new(server->e->event_base,
		  server_input_handler, server,
		  LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE,
		  1024, tls_listen_fd);

  if(!(server->l)) {
	  TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot create TLS listener\n");
	  socket_closesocket(tls_listen_fd);
	  return -1;
  }

  if(addr_get_from_sock(tls_listen_fd, &(server->addr))) {
    perror("Cannot get local socket addr");
    socket_closesocket(tls_listen_fd);
    return -1;
  }

  if(!no_tcp && !no_tls)
	  addr_debug_print(server->verbose, &server->addr,"TCP/TLS listener opened on ");
  else if(!no_tls)
	  addr_debug_print(server->verbose, &server->addr,"TLS listener opened on ");
  else if(!no_tcp)
	  addr_debug_print(server->verbose, &server->addr,"TCP listener opened on ");

  FUNCEND;
  
  return 0;
}
static int create_server_socket(dtls_listener_relay_server_type* server) {

  FUNCSTART;

  if(!server) return -1;

  clean_server(server);

  ioa_socket_raw udp_listen_fd = -1;

  udp_listen_fd = socket(server->addr.ss.ss_family, SOCK_DGRAM, 0);
  if (udp_listen_fd < 0) {
    perror("socket");
    return -1;
  }

  server->udp_listen_s = create_ioa_socket_from_fd(server->e, udp_listen_fd, NULL, UDP_SOCKET, LISTENER_SOCKET, NULL, &(server->addr));

  server->udp_listen_s->listener_server = server;

  set_sock_buf_size(udp_listen_fd,UR_SERVER_SOCK_BUF_SIZE);

  if(sock_bind_to_device(udp_listen_fd, (unsigned char*)server->ifname)<0) {
    TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind listener socket to device %s\n",server->ifname);
  }

  if(addr_bind(udp_listen_fd,&server->addr)<0) {
	  perror("Cannot bind local socket to addr");
	  char saddr[129];
	  addr_to_string(&server->addr,(u08bits*)saddr);
	  TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind UDP/DTLS listener socket to addr %s\n",saddr);
	  return -1;
  }

  server->udp_listen_ev = event_new(server->e->event_base,udp_listen_fd,
				    EV_READ|EV_PERSIST,udp_server_input_handler,server);

  event_add(server->udp_listen_ev,NULL);

  if(addr_get_from_sock(udp_listen_fd, &(server->addr))) {
    perror("Cannot get local socket addr");
    return -1;
  }

  if(!no_udp && !no_dtls)
	  addr_debug_print(server->verbose, &server->addr,"UDP/DTLS listener opened on ");
  else if(!no_dtls)
	  addr_debug_print(server->verbose, &server->addr,"DTLS listener opened on ");
  else if(!no_udp)
	  addr_debug_print(server->verbose, &server->addr,"UDP listener opened on ");

  FUNCEND;
  
  return 0;
}
Example #3
0
int sock_create_multicast_writer(struct socket **sock, const char *local_if, const char *local_ip, const int local_port)
{
	if( -1 ==  sock_create_udp(sock) )
		return -1;

	if( local_if )
	{
		if( -1 == sock_bind_to_device(*sock, local_if) )
			goto err_out;
	}

	if( -1 == _omni_sock_bind_localaddr(*sock, local_ip, local_port) )
		goto err_out;

	return 0;

err_out:
	sock_release(*sock);
	return -1;
}
Example #4
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 reopen_server_socket(dtls_listener_relay_server_type* server)
{
	if(!server)
		return 0;

	FUNCSTART;

	EVENT_DEL(server->udp_listen_ev);

	if(server->udp_listen_s->fd>=0) {
		socket_closesocket(server->udp_listen_s->fd);
		server->udp_listen_s->fd = -1;
	}

	if (!(server->udp_listen_s)) {
		return create_server_socket(server);
	}

	ioa_socket_raw udp_listen_fd = socket(server->addr.ss.ss_family, SOCK_DGRAM, 0);
	if (udp_listen_fd < 0) {
		perror("socket");
		FUNCEND;
		return -1;
	}

	server->udp_listen_s->fd = udp_listen_fd;

	/* some UDP sessions may fail due to the race condition here */

	set_socket_options(server->udp_listen_s);

	set_sock_buf_size(udp_listen_fd, UR_SERVER_SOCK_BUF_SIZE);

	if (sock_bind_to_device(udp_listen_fd, (unsigned char*) server->ifname) < 0) {
			TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,
			"Cannot bind listener socket to device %s\n",
			server->ifname);
	}

	if(addr_bind(udp_listen_fd,&server->addr)<0) {
		  perror("Cannot bind local socket to addr");
		  char saddr[129];
		  addr_to_string(&server->addr,(u08bits*)saddr);
		  TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind listener socket to addr %s\n",saddr);
		  return -1;
	}

	server->udp_listen_ev = event_new(server->e->event_base, udp_listen_fd,
				EV_READ | EV_PERSIST, udp_server_input_handler, server);

	event_add(server->udp_listen_ev, NULL );

	if (!no_udp && !no_dtls)
		addr_debug_print(server->verbose, &server->addr,
					"UDP/DTLS listener opened on ");
	else if (!no_dtls)
		addr_debug_print(server->verbose, &server->addr,
					"DTLS listener opened on ");
	else if (!no_udp)
		addr_debug_print(server->verbose, &server->addr,
				"UDP listener opened on ");

	FUNCEND;

	return 0;
}
Example #6
0
static int create_server_socket(dtls_listener_relay_server_type* server, int report_creation) {

  FUNCSTART;

  if(!server) return -1;

  clean_server(server);

  {
	  ioa_socket_raw udp_listen_fd = -1;

	  udp_listen_fd = socket(server->addr.ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL);
	  if (udp_listen_fd < 0) {
		  perror("socket");
		  return -1;
	  }

	  server->udp_listen_s = create_ioa_socket_from_fd(server->e, udp_listen_fd, NULL, UDP_SOCKET, LISTENER_SOCKET, NULL, &(server->addr));

	  set_sock_buf_size(udp_listen_fd,UR_SERVER_SOCK_BUF_SIZE);

	  if(sock_bind_to_device(udp_listen_fd, (unsigned char*)server->ifname)<0) {
		  TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind listener socket to device %s\n",server->ifname);
	  }

	  set_raw_socket_ttl_options(udp_listen_fd, server->addr.ss.sa_family);
	  set_raw_socket_tos_options(udp_listen_fd, server->addr.ss.sa_family);

	  {
		  const int max_binding_time = 60;
		  int addr_bind_cycle = 0;
		  retry_addr_bind:

		  if(addr_bind(udp_listen_fd,&server->addr,1,1,UDP_SOCKET)<0) {
			  perror("Cannot bind local socket to addr");
			  char saddr[129];
			  addr_to_string(&server->addr,(u08bits*)saddr);
			  TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"Cannot bind DTLS/UDP listener socket to addr %s\n",saddr);
			  if(addr_bind_cycle++<max_binding_time) {
				  TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Trying to bind DTLS/UDP listener socket to addr %s, again...\n",saddr);
				  sleep(1);
				  goto retry_addr_bind;
			  }
			  TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Fatal final failure: cannot bind DTLS/UDP listener socket to addr %s\n",saddr);
			  exit(-1);
		  }
	  }

	  server->udp_listen_ev = event_new(server->e->event_base,udp_listen_fd,
				    EV_READ|EV_PERSIST,udp_server_input_handler,
				    server);

	  event_add(server->udp_listen_ev,NULL);
  }

  if(report_creation) {
	  if(!turn_params.no_udp && !turn_params.no_dtls)
		  addr_debug_print(server->verbose, &server->addr,"DTLS/UDP listener opened on");
	  else if(!turn_params.no_dtls)
		  addr_debug_print(server->verbose, &server->addr,"DTLS listener opened on");
	  else if(!turn_params.no_udp)
		  addr_debug_print(server->verbose, &server->addr,"UDP listener opened on");
  }

  FUNCEND;
  
  return 0;
}
Example #7
0
static int create_new_connected_udp_socket(
		dtls_listener_relay_server_type* server, ioa_socket_handle s)
{

	evutil_socket_t udp_fd = socket(s->local_addr.ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL);
	if (udp_fd < 0) {
		perror("socket");
		TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot allocate new socket\n",
				__FUNCTION__);
		return -1;
	}

	if (sock_bind_to_device(udp_fd, (unsigned char*) (s->e->relay_ifname))
			< 0) {
		TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
				"Cannot bind udp server socket to device %s\n",
				(char*) (s->e->relay_ifname));
	}

	ioa_socket_handle ret = (ioa_socket*) turn_malloc(sizeof(ioa_socket));
	if (!ret) {
		TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
				"%s: Cannot allocate new socket structure\n", __FUNCTION__);
		close(udp_fd);
		return -1;
	}

	ns_bzero(ret, sizeof(ioa_socket));

	ret->magic = SOCKET_MAGIC;

	ret->fd = udp_fd;

	ret->family = s->family;
	ret->st = s->st;
	ret->sat = CLIENT_SOCKET;
	ret->local_addr_known = 1;
	addr_cpy(&(ret->local_addr), &(s->local_addr));

	if (addr_bind(udp_fd,&(s->local_addr),1,1,UDP_SOCKET) < 0) {
		TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
				"Cannot bind new detached udp server socket to local addr\n");
		IOA_CLOSE_SOCKET(ret);
		return -1;
	}
	ret->bound = 1;

	{
		int connect_err = 0;
		if (addr_connect(udp_fd, &(server->sm.m.sm.nd.src_addr), &connect_err) < 0) {
			char sl[129];
			char sr[129];
			addr_to_string(&(ret->local_addr),(u08bits*)sl);
			addr_to_string(&(server->sm.m.sm.nd.src_addr),(u08bits*)sr);
			TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
					"Cannot connect new detached udp client socket from local addr %s to remote addr %s\n",sl,sr);
			IOA_CLOSE_SOCKET(ret);
			return -1;
		}
	}
	ret->connected = 1;
	addr_cpy(&(ret->remote_addr), &(server->sm.m.sm.nd.src_addr));

	set_socket_options(ret);

	ret->current_ttl = s->current_ttl;
	ret->default_ttl = s->default_ttl;

	ret->current_tos = s->current_tos;
	ret->default_tos = s->default_tos;

#if DTLS_SUPPORTED
	if (!turn_params.no_dtls
			&& is_dtls_handshake_message(
					ioa_network_buffer_data(server->sm.m.sm.nd.nbh),
					(int) ioa_network_buffer_get_size(
							server->sm.m.sm.nd.nbh))) {

		SSL* connecting_ssl = NULL;

		BIO *wbio = NULL;
		struct timeval timeout;

		/* Create BIO */
		wbio = BIO_new_dgram(ret->fd, BIO_NOCLOSE);
		(void) BIO_dgram_set_peer(wbio, (struct sockaddr*) &(server->sm.m.sm.nd.src_addr));

		BIO_ctrl(wbio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &(server->sm.m.sm.nd.src_addr));

		/* Set and activate timeouts */
		timeout.tv_sec = DTLS_MAX_RECV_TIMEOUT;
		timeout.tv_usec = 0;
		BIO_ctrl(wbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);

#if DTLSv1_2_SUPPORTED
		if(get_dtls_version(ioa_network_buffer_data(server->sm.m.sm.nd.nbh),
							(int)ioa_network_buffer_get_size(server->sm.m.sm.nd.nbh)) == 1) {
			connecting_ssl = SSL_NEW(server->dtls_ctx_v1_2);
		} else {
			connecting_ssl = SSL_NEW(server->dtls_ctx);
		}
#else
		{
			connecting_ssl = SSL_NEW(server->dtls_ctx);
		}
#endif

		SSL_set_accept_state(connecting_ssl);

		SSL_set_bio(connecting_ssl, NULL, wbio);

		SSL_set_options(connecting_ssl, SSL_OP_COOKIE_EXCHANGE);
		SSL_set_max_cert_list(connecting_ssl, 655350);
		int rc = ssl_read(ret->fd, connecting_ssl, server->sm.m.sm.nd.nbh,
				server->verbose);

		if (rc < 0) {
			if (!(SSL_get_shutdown(connecting_ssl) & SSL_SENT_SHUTDOWN)) {
				SSL_set_shutdown(connecting_ssl, SSL_RECEIVED_SHUTDOWN);
				SSL_shutdown(connecting_ssl);
			}
			SSL_FREE(connecting_ssl);
			IOA_CLOSE_SOCKET(ret);
			return -1;
		}

		addr_debug_print(server->verbose, &(server->sm.m.sm.nd.src_addr),
				"Accepted DTLS connection from");

		ret->ssl = connecting_ssl;

		ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh);
		server->sm.m.sm.nd.nbh = NULL;

		ret->st = DTLS_SOCKET;
	}
#endif

	server->sm.m.sm.s = ret;
	return server->connect_cb(server->e, &(server->sm));
}
Example #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;
}
Example #9
0
void tcp_data_connect(app_ur_session *elem, u32bits cid)
{
	int clnet_fd;
	int connect_cycle = 0;

	again:

	clnet_fd = socket(elem->pinfo.remote_addr.ss.sa_family, CLIENT_STREAM_SOCKET_TYPE, CLIENT_STREAM_SOCKET_PROTOCOL);
	if (clnet_fd < 0) {
		perror("socket");
		exit(-1);
	}

	if (sock_bind_to_device(clnet_fd, client_ifname) < 0) {
		TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,
						"Cannot bind client socket to device %s\n", client_ifname);
	}
	set_sock_buf_size(clnet_fd, (UR_CLIENT_SOCK_BUF_SIZE<<2));

	++elem->pinfo.tcp_conn_number;
	int i = (int)(elem->pinfo.tcp_conn_number-1);
	elem->pinfo.tcp_conn=(app_tcp_conn_info**)turn_realloc(elem->pinfo.tcp_conn,0,elem->pinfo.tcp_conn_number*sizeof(app_tcp_conn_info*));
	elem->pinfo.tcp_conn[i]=(app_tcp_conn_info*)turn_malloc(sizeof(app_tcp_conn_info));
	ns_bzero(elem->pinfo.tcp_conn[i],sizeof(app_tcp_conn_info));

	elem->pinfo.tcp_conn[i]->tcp_data_fd = clnet_fd;
	elem->pinfo.tcp_conn[i]->cid = cid;

	addr_cpy(&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr),&(elem->pinfo.local_addr));

	addr_set_port(&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr),0);

	addr_bind(clnet_fd, &(elem->pinfo.tcp_conn[i]->tcp_data_local_addr), 1, 1, TCP_SOCKET);

	addr_get_from_sock(clnet_fd,&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr));

	{
	  int cycle = 0;
	  while(cycle++<1024) {
	    int err = 0;
	    if (addr_connect(clnet_fd, &(elem->pinfo.remote_addr),&err) < 0) {
	      if(err == EADDRINUSE) {
	    	  socket_closesocket(clnet_fd);
	    	  clnet_fd = socket(elem->pinfo.remote_addr.ss.sa_family, CLIENT_STREAM_SOCKET_TYPE, CLIENT_STREAM_SOCKET_PROTOCOL);
	    	  if (clnet_fd < 0) {
	    		  perror("socket");
	    		  exit(-1);
	    	  }
	    	  if (sock_bind_to_device(clnet_fd, client_ifname) < 0) {
	    		  TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,
	    				  "Cannot bind client socket to device %s\n", client_ifname);
	    	  }
	    	  set_sock_buf_size(clnet_fd, UR_CLIENT_SOCK_BUF_SIZE<<2);

	    	  elem->pinfo.tcp_conn[i]->tcp_data_fd = clnet_fd;

	    	  addr_cpy(&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr),&(elem->pinfo.local_addr));

	    	  addr_set_port(&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr),0);

	    	  addr_bind(clnet_fd, &(elem->pinfo.tcp_conn[i]->tcp_data_local_addr),1,1,TCP_SOCKET);

	    	  addr_get_from_sock(clnet_fd,&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr));

	    	  continue;

	      } else {
	    	  perror("connect");
	    	  TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,
			      "%s: cannot connect to remote addr\n", __FUNCTION__);
	    	  exit(-1);
	      }
	    } else {
	      break;
	    }
	  }
	}

	if(use_secure) {
		int try_again = 0;
		elem->pinfo.tcp_conn[i]->tcp_data_ssl = tls_connect(elem->pinfo.tcp_conn[i]->tcp_data_fd, &(elem->pinfo.remote_addr),&try_again, connect_cycle++);
		if(!(elem->pinfo.tcp_conn[i]->tcp_data_ssl)) {
			if(try_again) {
				--elem->pinfo.tcp_conn_number;
				goto again;
			}
			TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,
					"%s: cannot SSL connect to remote addr\n", __FUNCTION__);
			exit(-1);
		}
	}

	if(turn_tcp_connection_bind(clnet_verbose, &(elem->pinfo), elem->pinfo.tcp_conn[i],0)<0) {
		TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,
				"%s: cannot BIND to tcp connection\n", __FUNCTION__);
	} else {

		socket_set_nonblocking(clnet_fd);

		struct event* ev = event_new(client_event_base,clnet_fd,
					EV_READ|EV_PERSIST,client_input_handler,
					elem);

		event_add(ev,NULL);

		elem->input_tcp_data_ev = ev;

		addr_debug_print(clnet_verbose, &(elem->pinfo.remote_addr), "TCP data network connected to");
	}
}