Example #1
0
static ioa_socket_handle dtls_server_input_handler(dtls_listener_relay_server_type* server,
				ioa_socket_handle s,
				ioa_network_buffer_handle nbh)
{
	FUNCSTART;

	if (!server || !nbh) {
		return NULL;
	}

	SSL* connecting_ssl = NULL;

	BIO *wbio = NULL;
	struct timeval timeout;

	/* Create BIO */
	wbio = BIO_new_dgram(s->fd, BIO_NOCLOSE);
	(void)BIO_dgram_set_peer(wbio, (struct sockaddr*) &(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(nbh),
							(int)ioa_network_buffer_get_size(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);

	ioa_socket_handle rc = dtls_accept_client_connection(server, s, connecting_ssl,
					&(server->sm.m.sm.nd.src_addr),
					&(server->addr),
					nbh);

	if (!rc) {
		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);
	}

	return rc;
}
Example #2
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 #3
0
static SSL* tls_connect(ioa_socket_raw fd, ioa_addr *remote_addr, int *try_again, int connect_cycle)
{

	int ctxtype = (int)(((unsigned long)random())%root_tls_ctx_num);

	SSL *ssl;

	ssl = SSL_NEW(root_tls_ctx[ctxtype]);

#if ALPN_SUPPORTED
	SSL_set_alpn_protos(ssl, kALPNProtos, kALPNProtosLen);
#endif

	if(use_tcp) {
		SSL_set_fd(ssl, fd);
	} else {
#if !DTLS_SUPPORTED
	  UNUSED_ARG(remote_addr);
	  fprintf(stderr,"ERROR: DTLS is not supported.\n");
	  exit(-1);
#else
		/* Create BIO, connect and set to already connected */
		BIO *bio = BIO_new_dgram(fd, BIO_CLOSE);
		//bio = BIO_new_socket(fd, BIO_CLOSE);

		BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &remote_addr->ss);

		SSL_set_bio(ssl, bio, bio);

		{
			struct timeval timeout;
			/* Set and activate timeouts */
			timeout.tv_sec = DTLS_MAX_CONNECT_TIMEOUT;
			timeout.tv_usec = 0;
			BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
		}

		set_mtu_df(ssl, fd, remote_addr->ss.sa_family, SOSO_MTU, !use_tcp, clnet_verbose);
#endif
	}

	SSL_set_max_cert_list(ssl, 655350);

	if (clnet_verbose)
		TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "call SSL_connect...\n");

	int rc = 0;

	do {
		do {
			rc = SSL_connect(ssl);
		} while (rc < 0 && errno == EINTR);
		int orig_errno = errno;
		if (rc > 0) {
		  TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s: client session connected with cipher %s, method=%s\n",__FUNCTION__,
				  SSL_get_cipher(ssl),turn_get_ssl_method(ssl,NULL));
		  if(clnet_verbose && SSL_get_peer_certificate(ssl)) {
			  TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "------------------------------------------------------------\n");
		  	X509_NAME_print_ex_fp(stdout, X509_get_subject_name(SSL_get_peer_certificate(ssl)), 1,
		  						XN_FLAG_MULTILINE);
		  	TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n\n Cipher: %s\n", SSL_CIPHER_get_name(SSL_get_current_cipher(ssl)));
		  	TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n------------------------------------------------------------\n\n");
		  }
		  break;
		} else {
			TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: cannot connect: rc=%d, ctx=%d\n",
					__FUNCTION__,rc,ctxtype);

			switch (SSL_get_error(ssl, rc)) {
			case SSL_ERROR_WANT_READ:
			case SSL_ERROR_WANT_WRITE:
				if(!dos) usleep(1000);
				continue;
			default: {
				char buf[1025];
				TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "errno=%d, err=%d, %s (%d)\n",orig_errno,
								(int)ERR_get_error(), ERR_error_string(ERR_get_error(), buf), (int)SSL_get_error(ssl, rc));
				if(connect_cycle<MAX_TLS_CYCLES) {
					if(try_again) {
						SSL_FREE(ssl);
						*try_again = 1;
						return NULL;
					}
				}
				exit(-1);
			}
			};
		}
	} while (1);

	if (clnet_verbose && SSL_get_peer_certificate(ssl)) {
		if(use_tcp) {
			TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,
				"------TLS---------------------------------------------------\n");
		} else {
			TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,
				"------DTLS---------------------------------------------------\n");
		}
		X509_NAME_print_ex_fp(stdout, X509_get_subject_name(
				SSL_get_peer_certificate(ssl)), 1, XN_FLAG_MULTILINE);
		TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n\n Cipher: %s\n",
				SSL_CIPHER_get_name(SSL_get_current_cipher(ssl)));
		TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,
				"\n------------------------------------------------------------\n\n");
	}

	return ssl;
}