예제 #1
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;
}
예제 #2
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;
}
예제 #3
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;
}
예제 #4
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;
}
예제 #5
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;
}
예제 #6
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");
	}
}
예제 #7
0
static void main_loop(const char *serverIp, Uint16 port)
{
	int sockTcp = socket_tcp_server(56790, 5);
	assert(sockTcp >= 0);
	int sockUdp = socket_udp_server(56790);
	assert(sockUdp >= 0);

	int err = set_sock_send_timeout(sockTcp, 5);
	err |= set_sock_recv_timeout(sockTcp, 5);
	assert(err == 0);

	err = set_sock_buf_size(sockUdp, 512 * 1024, 512 * 1024);
	err |= set_sock_linger(sockUdp, TRUE, 2);
	err |= set_sock_block(sockUdp, FALSE);
	DBG("err = %d", err);
	assert(err == 0);

	close(sockTcp);
	close(sockUdp);

	sockTcp = socket(AF_INET, SOCK_STREAM, 0);
	struct sockaddr_in addr;
	init_sock_addr(&addr, serverIp, port);

	err = connect_nonblock(sockTcp, (struct sockaddr *)&addr, sizeof(addr), 5000);
	if(err < 0) {
		ERR("Connect nonblocking server failed.");
		goto exit;
	} else {
		DBG("Connect to %s:%u success!", serverIp, port);
	}

	close(sockTcp);
	close(sockUdp);
	sockTcp = sockUdp = -1;
	
	sockTcp = socket(AF_INET, SOCK_STREAM, 0);
	err = connect(sockTcp, (struct sockaddr *)&addr, sizeof(addr));
	if(err < 0) {
		ERR("Connect server failed.");
		goto exit;
	} else {
		DBG("Connect to %s:%u success!", serverIp, port);
	}

	sockUdp = socket(AF_INET, SOCK_DGRAM, 0);
	char *sendLine = "Hello";
	err = sendto(sockUdp, sendLine, strlen(sendLine), 0, (struct sockaddr *)&addr, sizeof(addr));
	if(err < 0)
		ERR("Send to failed.");
	else
		DBG("Sendto ok...");

	char ipBuf[32];

	err = get_local_ip(ipBuf, sizeof(ipBuf));
	assert(err == E_NO);
	DBG("get local ip: %s", ipBuf);

	Uint8 macAddr[6];
	err = sys_get_mac("eth0", macAddr, sizeof(macAddr));
	assert(err == E_NO);
	DBG("get mac addr: %02X-%02X-%02X-%02X-%02X-%02X", 
		macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]);

exit:

	if(sockTcp > 0)
		close(sockTcp);
	if(sockUdp > 0)
		close(sockUdp);
	
}