예제 #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 void server_input_handler(struct evconnlistener *l, evutil_socket_t fd,
				struct sockaddr *sa, int socklen, void *arg)
{

	UNUSED_ARG(l);

	tcp_listener_relay_server_type * server = (tcp_listener_relay_server_type*) arg;

	if(!(server->e->connect_cb)) {
		close(fd);
		return;
	}

	FUNCSTART;

	if (!server)
		return;

	if (server->stats)
		++(*(server->stats));

	ioa_addr client_addr;
	ns_bcopy(sa,&client_addr,socklen);

	addr_debug_print(server->verbose, &client_addr,"tcp connected to");

	ioa_socket_handle ioas =
				create_ioa_socket_from_fd(
							server->e,
							fd,
							TCP_SOCKET,
							CLIENT_SOCKET,
							&client_addr,
							&(server->addr));

	if (ioas) {
		ioa_net_data nd = { &client_addr, NULL, 0, TTL_IGNORE, TOS_IGNORE };
		int rc = server->e->connect_cb(server->e, ioas, &nd);

		if (rc < 0) {
			TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
					"Cannot create tcp session\n");
			IOA_CLOSE_SOCKET(ioas);
		}
	} else {
		TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
				"Cannot create ioa_socket from FD\n");
		close(fd);
	}

	FUNCEND	;
}
예제 #3
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;
}
예제 #4
0
static int handle_udp_packet(dtls_listener_relay_server_type *server,
				struct message_to_relay *sm,
				ioa_engine_handle ioa_eng, turn_turnserver *ts)
{
	int verbose = ioa_eng->verbose;
	ioa_socket_handle s = sm->m.sm.s;

	ur_addr_map_value_type mvt = 0;
	ur_addr_map *amap = server->children_ss;

	ioa_socket_handle chs = NULL;
	if ((ur_addr_map_get(amap, &(sm->m.sm.nd.src_addr), &mvt) > 0) && mvt) {
		chs = (ioa_socket_handle) mvt;
	}

	if (chs && !ioa_socket_tobeclosed(chs)
			&& (chs->sockets_container == amap)
			&& (chs->magic == SOCKET_MAGIC)) {
		s = chs;
		sm->m.sm.s = s;
		if(s->ssl) {
			int read_len = (int)ioa_network_buffer_get_size(sm->m.sm.nd.nbh);
			int sslret = ssl_read(s->fd, s->ssl, (s08bits*)ioa_network_buffer_data(sm->m.sm.nd.nbh),
				(int)ioa_network_buffer_get_capacity(),
				verbose, &read_len);
			if(sslret < 0) {
				ioa_network_buffer_delete(ioa_eng, sm->m.sm.nd.nbh);
				sm->m.sm.nd.nbh = NULL;
				ts_ur_super_session *ss = (ts_ur_super_session *) s->session;
				if (ss) {
					turn_turnserver *server = (turn_turnserver *) ss->server;
					if (server) {
						shutdown_client_connection(server, ss);
					}
				} else {
					close_ioa_socket(s);
				}
				ur_addr_map_del(amap, &(sm->m.sm.nd.src_addr), NULL);
				sm->m.sm.s = NULL;
				s = NULL;
				chs = NULL;
			} else if(read_len>0) {
				ioa_network_buffer_set_size(sm->m.sm.nd.nbh,(size_t)read_len);
			} else {
				ioa_network_buffer_delete(ioa_eng, sm->m.sm.nd.nbh);
				sm->m.sm.nd.nbh = NULL;
			}
		}

		if (s && s->read_cb && sm->m.sm.nd.nbh) {
			s->e = ioa_eng;
			s->read_cb(s, IOA_EV_READ, &(sm->m.sm.nd), s->read_ctx);
			ioa_network_buffer_delete(ioa_eng, sm->m.sm.nd.nbh);
			sm->m.sm.nd.nbh = NULL;

			if (ioa_socket_tobeclosed(s)) {
				ts_ur_super_session *ss = (ts_ur_super_session *) s->session;
				if (ss) {
					turn_turnserver *server = (turn_turnserver *) ss->server;
					if (server) {
						shutdown_client_connection(server, ss);
					}
				}
			}
		}
	} else {
		if (chs && ioa_socket_tobeclosed(chs)) {
			TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
					"%s: socket to be closed\n", __FUNCTION__);
			{
				u08bits saddr[129];
				u08bits rsaddr[129];
				long thrid = 0;
#if !defined(TURN_NO_THREADS)
				thrid = (long) pthread_self();
#endif
				addr_to_string(get_local_addr_from_ioa_socket(chs),saddr);
				addr_to_string(get_remote_addr_from_ioa_socket(chs),rsaddr);
				TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,
					"%s: thrid=0x%lx: Amap = 0x%lx, socket container=0x%lx, local addr %s, remote addr %s, s=0x%lx, done=%d, tbc=%d\n",
					__FUNCTION__, thrid, (long) amap,
					(long) (chs->sockets_container), (char*) saddr,
					(char*) rsaddr, (long) s, (int) (chs->done),
					(int) (chs->tobeclosed));
			}
		}

		if (chs && (chs->magic != SOCKET_MAGIC)) {
			TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
					"%s: wrong socket magic\n", __FUNCTION__);
		}

		if (chs && (chs->sockets_container != amap)) {
			TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
					"%s: wrong socket container\n", __FUNCTION__);
			{
				u08bits saddr[129];
				u08bits rsaddr[129];
				long thrid = 0;
#if !defined(TURN_NO_THREADS)
				thrid = (long) pthread_self();
#endif
				addr_to_string(get_local_addr_from_ioa_socket(chs),saddr);
				addr_to_string(get_remote_addr_from_ioa_socket(chs),rsaddr);
				TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,
					"%s: thrid=0x%lx: Amap = 0x%lx, socket container=0x%lx, local addr %s, remote addr %s, s=0x%lx, done=%d, tbc=%d, st=%d, sat=%d\n",
					__FUNCTION__, thrid, (long) amap,
					(long) (chs->sockets_container), (char*) saddr,
					(char*) rsaddr, (long) chs, (int) (chs->done),
					(int) (chs->tobeclosed), (int) (chs->st),
					(int) (chs->sat));
			}
		}

		chs = NULL;

#if !defined(TURN_NO_DTLS)
		if (!no_dtls &&
			is_dtls_handshake_message(ioa_network_buffer_data(sm->m.sm.nd.nbh),
			(int)ioa_network_buffer_get_size(sm->m.sm.nd.nbh))) {
			chs = dtls_server_input_handler(server,
				ioa_network_buffer_data(sm->m.sm.nd.nbh),
				(int)ioa_network_buffer_get_size(sm->m.sm.nd.nbh));
			ioa_network_buffer_delete(server->e, sm->m.sm.nd.nbh);
			sm->m.sm.nd.nbh = NULL;
		}
#endif

		if(!chs) {
			chs = create_ioa_socket_from_fd(ioa_eng, s->fd, s,
				UDP_SOCKET, CLIENT_SOCKET, &(sm->m.sm.nd.src_addr),
				get_local_addr_from_ioa_socket(s));
		}

		s = chs;
		sm->m.sm.s = s;

		if (s) {
			if(verbose) {
				u08bits saddr[129];
				u08bits rsaddr[129];
				addr_to_string(get_local_addr_from_ioa_socket(s),saddr);
				addr_to_string(get_remote_addr_from_ioa_socket(s),rsaddr);
				TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,
					"%s: New UDP endpoint: local addr %s, remote addr %s\n",
					__FUNCTION__, (char*) saddr,(char*) rsaddr);
			}
			s->e = ioa_eng;
			add_socket_to_map(s, amap);
			open_client_connection_session(ts, &(sm->m.sm));
		}
	}

	return 0;
}
예제 #5
0
static void server_input_handler(struct evconnlistener *l, evutil_socket_t fd,
				struct sockaddr *sa, int socklen, void *arg)
{

	UNUSED_ARG(l);

	tls_listener_relay_server_type * server = (tls_listener_relay_server_type*) arg;

	if(!(server->connect_cb)) {
		socket_closesocket(fd);
		return;
	}

	FUNCSTART;

	if (!server)
		return;

	ns_bcopy(sa,&(server->sm.m.sm.nd.src_addr),socklen);

	addr_debug_print(server->verbose, &(server->sm.m.sm.nd.src_addr),"tcp or tls connected to");

	SOCKET_TYPE st = TENTATIVE_TCP_SOCKET;

	if(no_tls)
		st = TCP_SOCKET;
	else if(no_tcp)
		st = TLS_SOCKET;

	ioa_socket_handle ioas =
				create_ioa_socket_from_fd(
							server->e,
							fd,
							NULL,
							st,
							CLIENT_SOCKET,
							&(server->sm.m.sm.nd.src_addr),
							&(server->addr));

	if (ioas) {

		ioas->listener_server = server;

		server->sm.m.sm.nd.recv_ttl = TTL_IGNORE;
		server->sm.m.sm.nd.recv_tos = TOS_IGNORE;
		server->sm.m.sm.nd.nbh = NULL;
		server->sm.m.sm.s = ioas;
		server->sm.relay_server = server->relay_server;

		int rc = server->connect_cb(server->e, &(server->sm));

		if (rc < 0) {
			TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
					"Cannot create tcp or tls session\n");
		}
	} else {
		TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
				"Cannot create ioa_socket from FD\n");
		socket_closesocket(fd);
	}

	FUNCEND	;
}