Beispiel #1
0
/**
 * \brief This function is main function of new thread for client
 * \param *arg	The pointer at verse client session
 */
static void *vc_new_session_thread(void *arg)
{
	struct VSession *vsession = (struct VSession*)arg;
	int i;

	/* Start "never ending" thread of connection*/
	vc_main_stream_loop(vc_ctx, vsession);

	pthread_mutex_lock(&vc_ctx->mutex);

	/* Find this session in Verse client session list */
	for(i=0; i<vc_ctx->max_sessions; i++) {
		if(vc_ctx->vsessions[i] != NULL) {
			if(strcmp(vc_ctx->vsessions[i]->peer_hostname, vsession->peer_hostname)==0 &&
					strcmp(vc_ctx->vsessions[i]->service, vsession->service)==0) {
				vc_ctx->vsessions[i] = NULL;
				break;
			}
		}
	}

	/* When connection is closed, then destroy this session*/
	v_destroy_session(vsession);
	free(vsession);

	pthread_mutex_unlock(&vc_ctx->mutex);

	return NULL;
}
Beispiel #2
0
/**
 * \brief Destroy Verse server context
 *
 * \param[in]	vs_ctx	The Verse server context.
 */
static void vs_destroy_ctx(struct VS_CTX *vs_ctx)
{
	struct VSUser *user;
	int i;

	/* Free all data shared at verse server */
	vs_node_destroy_branch(vs_ctx, vs_ctx->data.root_node, 0);

	/* Destroy hashed array of nodes */
	v_hash_array_destroy(&vs_ctx->data.nodes);

	/* Destroy list of connections */
	for (i=0; i<vs_ctx->max_sessions; i++) {
		if(vs_ctx->vsessions[i] != NULL) {
			v_destroy_session(vs_ctx->vsessions[i]);
			free(vs_ctx->vsessions[i]);
			vs_ctx->vsessions[i] = NULL;
		}
	}

	free(vs_ctx->vsessions); vs_ctx->vsessions = NULL;

	free(vs_ctx->port_list); vs_ctx->port_list = NULL;

	free(vs_ctx->tcp_io_ctx.buf); vs_ctx->tcp_io_ctx.buf = NULL;

	free(vs_ctx->private_cert_file); vs_ctx->private_cert_file = NULL;
	if(vs_ctx->ca_cert_file != NULL) {
		free(vs_ctx->ca_cert_file);
		vs_ctx->ca_cert_file = NULL;
	}
	free(vs_ctx->public_cert_file); vs_ctx->public_cert_file = NULL;

	free(vs_ctx->hostname); vs_ctx->hostname = NULL;

	free(vs_ctx->ded); vs_ctx->ded = NULL;

	if(vs_ctx->csv_user_file != NULL) {
		free(vs_ctx->csv_user_file);
		vs_ctx->csv_user_file = NULL;
	}

	user = (struct VSUser*)vs_ctx->users.first;
	while(user != NULL) {
		vs_user_free(user);
		user = user->next;
	}
	v_list_free(&vs_ctx->users);

#ifdef WITH_OPENSSL
	vs_destroy_stream_ctx(vs_ctx);
#endif
}
Beispiel #3
0
/**
 * \brief Free verse client context
 */
void vc_free_ctx(VC_CTX *vc_ctx)
{
	int i;
	for(i=0; i<vc_ctx->max_sessions; i++) {
		if(vc_ctx->vsessions[i]!=NULL) {
			v_destroy_session(vc_ctx->vsessions[i]);
			free(vc_ctx->vsessions[i]);
			vc_ctx->vsessions[i] = NULL;
		}
	}
	free(vc_ctx->ca_path);
	if(vc_ctx->client_name) free(vc_ctx->client_name);
	if(vc_ctx->client_version) free(vc_ctx->client_version);
}
Beispiel #4
0
int32_t vrs_send_connect_request(const char *hostname,
		const char *service,
		const uint16_t flags,
		uint8_t *session_id)
{
	struct VSession *vsession = NULL;
	uint16 _flags = flags;
	int already_connected = 0, i, ret;

	/* Check if CTX was initialized (initialization is done) */
	if(vc_ctx == NULL) {
		v_print_log(VRS_PRINT_ERROR,
				"Basic callback functions were not set.\n");
		return VRS_NO_CB_FUNC;
	} else {
		/* Check if all needed callback functions was set up */
		if(vc_ctx->vfs.receive_connect_accept == NULL) {
			v_print_log(VRS_PRINT_ERROR,
					"receive_connect_accept() callback functions was not set.\n");
			return VRS_NO_CB_CONN_FUNC;
		}
		if(vc_ctx->vfs.receive_connect_terminate == NULL) {
			v_print_log(VRS_PRINT_ERROR,
					"receive_connect_terminate() callback functions was not set.\n");
			return VRS_NO_CB_TERM_FUNC;
		}
		if(vc_ctx->vfs.receive_user_authenticate == NULL) {
			v_print_log(VRS_PRINT_ERROR,
					"receive_user_authenticat() callback functions was not set.\n");
			return VRS_NO_CB_USER_AUTH;
		}
	}

	/* Set security protocol */
#if OPENSSL_VERSION_NUMBER >= 0x10000000
	/* Check consistency of flags */
	if((_flags & VRS_SEC_DATA_NONE) && (_flags & VRS_SEC_DATA_TLS)) {
		if(is_log_level(VRS_PRINT_ERROR))
			v_print_log(VRS_PRINT_ERROR,
					"VRS_SEC_DATA_NONE or VRS_SEC_DATA_TLS could be set, not both.\n");
		return VRS_FAILURE;
	}
#else
	if (_flags & VRS_SEC_DATA_TLS) {
		v_print_log(VRS_PRINT_WARNING,
				"flag VRS_SEC_DATA_TLS could be set due to low version of OpenSSL (at least 1.0 is required).\n");
		_flags &= ~VRS_SEC_DATA_TLS;
		_flags |= VRS_SEC_DATA_NONE;
	}
#endif

	/* Set transport protocol */
	if((_flags & VRS_TP_UDP) && (_flags & VRS_TP_TCP)) {
		if(is_log_level(VRS_PRINT_ERROR))
			v_print_log(VRS_PRINT_ERROR,
					"VRS_TP_UDP or VRS_TP_TCP could be set, not both.\n");
		return VRS_FAILURE;
	} else if(!(_flags & VRS_TP_UDP) && !(_flags & VRS_TP_TCP)) {
		/* When no transport protocol is selected, then use UDP as default */
		_flags |= VRS_TP_UDP;
	}

	pthread_mutex_lock(&vc_ctx->mutex);

	/* Check if this client isn't already connected to this server or isn't
	 * trying to connect to the server with hostname:service */
	for(i=0; i<vc_ctx->max_sessions; i++) {
		if(vc_ctx->vsessions[i] != NULL) {
			if(strcmp(vc_ctx->vsessions[i]->peer_hostname, hostname) == 0 &&
					strcmp(vc_ctx->vsessions[i]->service, service) == 0) {
				v_print_log(VRS_PRINT_ERROR, "Client already connected to this server.\n");
				already_connected = 1;
				break;
			}
		}
	}

	if(already_connected == 0) {
		/* Try to find free verse session slot */
		for(i=0; i<vc_ctx->max_sessions; i++) {
			/* When free VSession slot is found, then create new session */
			if(vc_ctx->vsessions[i]==NULL) {
				vsession = (struct VSession*)malloc(sizeof(struct VSession));
				v_init_session(vsession);
				vsession->peer_hostname = strdup(hostname);
				vsession->service = strdup(service);
				/* Copy flags */
				vsession->flags = _flags;
				vsession->in_queue = (struct VInQueue*)calloc(1, sizeof(VInQueue));
				v_in_queue_init(vsession->in_queue, IN_QUEUE_DEFAULT_MAX_SIZE);
				vsession->out_queue = (struct VOutQueue*)calloc(1, sizeof(VOutQueue));
				v_out_queue_init(vsession->out_queue, OUT_QUEUE_DEFAULT_MAX_SIZE);

				vc_ctx->vsessions[i] = vsession;
				break;
			}
		}
	}

	pthread_mutex_unlock(&vc_ctx->mutex);

	if(already_connected == 1) {
		return VRS_FAILURE;
	}

	/* Check if we found free slot for new session */
	if(vsession == NULL) {
		v_print_log(VRS_PRINT_DEBUG_MSG,
				"Maximal count of sessions: %d reached.\n",
				vc_ctx->max_sessions);
		return VRS_FAILURE;
	}

	vsession->session_id = vc_ctx->session_counter++;
	*session_id = vsession->session_id;

	/* Try to initialize thread attributes */
	if( (ret = pthread_attr_init(&vsession->tcp_thread_attr)) != 0 ) {
		if(is_log_level(VRS_PRINT_ERROR)) v_print_log(VRS_PRINT_ERROR, "pthread_attr_init(): %s\n", strerror(errno));
		return VRS_FAILURE;
	}

	/* Try to set thread attributes as detached */
	if( (ret = pthread_attr_setdetachstate(&vsession->tcp_thread_attr, PTHREAD_CREATE_DETACHED)) != 0) {
		if(is_log_level(VRS_PRINT_ERROR)) v_print_log(VRS_PRINT_ERROR, "pthread_attr_setdetachstate(): %s\n", strerror(errno));
		return VRS_FAILURE;
	}

	/* Create thread for new client session */
	if(pthread_create(&vsession->tcp_thread, &vsession->tcp_thread_attr, vc_new_session_thread, (void*)vsession) != 0) {
		if(is_log_level(VRS_PRINT_ERROR)) v_print_log(VRS_PRINT_ERROR, "Thread creation failed.\n");
		pthread_mutex_lock(&vc_ctx->mutex);
		v_destroy_session(vsession);
		free(vsession);
		vc_ctx->vsessions[i] = NULL;
		pthread_mutex_unlock(&vc_ctx->mutex);
		return VRS_FAILURE;
	}

	/* Destroy thread attributes */
	pthread_attr_destroy(&vsession->tcp_thread_attr);

	return VRS_SUCCESS;
}