示例#1
0
文件: ui.c 项目: SylvestreG/bitrig
/* Tear down a connection, can be phase 1 or 2.  */
static void
ui_teardown(char *cmd)
{
	struct sockaddr_in	 addr;
	struct sockaddr_in6	 addr6;
	struct sa		*sa;
	int			 phase;
	char			 name[201];

	/* If no phase is given, we default to phase 2. */
	phase = 2;
	if (sscanf(cmd, "t main %200s", name) == 1)
		phase = 1;
	else if (sscanf(cmd, "t quick %200s", name) == 1)
		phase = 2;
	else if (sscanf(cmd, "t %200s", name) != 1) {
		log_print("ui_teardown: command \"%s\" malformed", cmd);
		return;
	}
	LOG_DBG((LOG_UI, 10, "ui_teardown: teardown connection \"%s\", "
	    "phase %d", name, phase));

	bzero(&addr, sizeof(addr));
	bzero(&addr6, sizeof(addr6));

	if (inet_pton(AF_INET, name, &addr.sin_addr) == 1) {
		addr.sin_len = sizeof(addr);
		addr.sin_family = AF_INET;

		while ((sa = sa_lookup_by_peer((struct sockaddr *)&addr,
		    SA_LEN((struct sockaddr *)&addr), phase)) != 0) {
			if (sa->name)
				connection_teardown(sa->name);
			sa_delete(sa, 1);
		}
	} else if (inet_pton(AF_INET6, name, &addr6.sin6_addr) == 1) {
		addr6.sin6_len = sizeof(addr6);
		addr6.sin6_family = AF_INET6;

		while ((sa = sa_lookup_by_peer((struct sockaddr *)&addr6,
		    SA_LEN((struct sockaddr *)&addr6), phase)) != 0) {
			if (sa->name)
				connection_teardown(sa->name);
			sa_delete(sa, 1);
		}
	} else {
		if (phase == 2)
			connection_teardown(name);
		while ((sa = sa_lookup_by_name(name, phase)) != 0)
			sa_delete(sa, 1);
	}
}
示例#2
0
/* Teardown all SAs.  */
void
sa_teardown_all(void)
{
	int             i;
	struct sa      *sa, *next = 0;

	LOG_DBG((LOG_SA, 70, "sa_teardown_all:"));
	/* Get Phase 2 SAs.  */
	for (i = 0; i <= bucket_mask; i++)
		for (sa = LIST_FIRST(&sa_tab[i]); sa; sa = next) {
			next = LIST_NEXT(sa, link);
			if (sa->phase == 2) {
				/*
				 * Teardown the phase 2 SAs by name, similar
				 * to ui_teardown.
				 */
				LOG_DBG((LOG_SA, 70,
				    "sa_teardown_all: tearing down SA %s",
				    sa->name ? sa->name : "<unnamed>"));
				if (sa->name)
					connection_teardown(sa->name);
				sa_delete(sa, 1);
			}
		}
}
static void Outprocess_Destroy(MODULE_HANDLE moduleHandle)
{
	OUTPROCESS_HANDLE_DATA* handleData = moduleHandle;
	/*Codes_SRS_OUTPROCESS_MODULE_17_026: [ If module is NULL, this function shall do nothing. ]*/
	if (handleData != NULL)
	{
		/*tell remote module to stop*/
		int32_t messageSize = 0;
		/*Codes_SRS_OUTPROCESS_MODULE_17_028: [ This function shall construct a Destroy Message. ]*/
		void * destroyMessage = construct_destroy_message(handleData, &messageSize);
		if (destroyMessage != NULL)
		{
			/*Codes_SRS_OUTPROCESS_MODULE_17_029: [ This function shall send the Destroy Message on the control channel. ]*/
			int sendBytes;
			int retry_count = 0;
			do
			{
				sendBytes = nn_send(handleData->control_socket, &destroyMessage, NN_MSG, NN_DONTWAIT);
				if (sendBytes != messageSize)
				{
					// best effort - it's mostly likely our remote module isn't attached.
					retry_count++;
					if (retry_count > 10)
					{
						break;
					}
				}
			} while (sendBytes != messageSize);

			if (sendBytes != messageSize)
			{
				/*Codes_SRS_OUTPROCESS_MODULE_17_048: [ There is a possibility the module host process is no longer operational, therefore sending the destroy the Destroy Message shall be a best effort attempt. ]*/
				LogError("unable to send destroy control message [%p], continuing with module destroy", destroyMessage);
				nn_freemsg(destroyMessage);
			}
		}
		else
		{
			LogError("unable to create destroy control message, continuing with module destroy");
		}

		/*Codes_SRS_OUTPROCESS_MODULE_17_030: [ This function shall close the message channel socket. ]*/
		/*Codes_SRS_OUTPROCESS_MODULE_17_031: [ This function shall close the control channel socket. ]*/
		connection_teardown(handleData);
		/* then stop the threads */

		/*Codes_SRS_OUTPROCESS_MODULE_17_032: [ This function shall signal the messaging thread to close. ]*/
		shutdown_a_thread(&(handleData->message_receive_thread));
		/*Codes_SRS_OUTPROCESS_MODULE_17_049: [ This function shall signal the outgoing gateway message thread to close. ]*/
		shutdown_a_thread(&(handleData->message_send_thread));
		/*Codes_SRS_OUTPROCESS_MODULE_17_050: [ This function shall signal the control thread to close. ]*/
		shutdown_a_thread(&(handleData->control_thread));
		shutdown_a_thread(&(handleData->async_create_thread));

		/* Free remaining resources */
		/*Codes_SRS_OUTPROCESS_MODULE_17_034: [ This function shall release all resources created by this module. ]*/
		delete_strings(handleData);
		(void)Lock_Deinit(handleData->handle_lock);
		free(handleData);
	}
}
static MODULE_HANDLE Outprocess_Create(BROKER_HANDLE broker, const void* configuration)
{
	OUTPROCESS_HANDLE_DATA * module;
	if (
		(broker == NULL) ||
		(configuration == NULL)
		)
	{
		/*Codes_SRS_OUTPROCESS_MODULE_17_005: [ If broker or configuration are NULL, this function shall return NULL. ]*/
		LogError("invalid arguments for outprcess module. broker=[%p], configuration = [%p]", broker, configuration);
		module = NULL;
	}
	else
	{
		OUTPROCESS_MODULE_CONFIG * config = (OUTPROCESS_MODULE_CONFIG*)configuration;
		/*Codes_SRS_OUTPROCESS_MODULE_17_006: [ This function shall allocate memory for the MODULE_HANDLE. ]*/
		module = (OUTPROCESS_HANDLE_DATA*)malloc(sizeof(OUTPROCESS_HANDLE_DATA));
		if (module == NULL)
		{
			/*Codes_SRS_OUTPROCESS_MODULE_17_016: [ If any step in the creation fails, this function shall deallocate all resources and return NULL. ]*/
			LogError("allocation for module failed.");
		}
		else
		{
			/*Codes_SRS_OUTPROCESS_MODULE_17_007: [ This function shall intialize a lock for exclusive access to handle data. ]*/
			module->handle_lock = Lock_Init();
			if (module->handle_lock == NULL)
			{
				/*Codes_SRS_OUTPROCESS_MODULE_17_016: [ If any step in the creation fails, this function shall deallocate all resources and return NULL. ]*/
				LogError("unable to intialize module lock");
				free(module);
				module = NULL;
			}
			else
			{
				/*Codes_SRS_OUTPROCESS_MODULE_17_042: [ This function shall initialize a queue for outgoing gateway messages. ]*/
				module->outgoing_messages = MESSAGE_QUEUE_create();
				if (module->outgoing_messages == NULL)
				{
					LogError("unable to create outgoing message queue");
					Lock_Deinit(module->handle_lock);
					free(module);
					module = NULL;
				}
				else
				{
					if (connection_setup(module, config) < 0)
					{
						/*Codes_SRS_OUTPROCESS_MODULE_17_016: [ If any step in the creation fails, this function shall deallocate all resources and return NULL. ]*/
						LogError("unable to set up connections");
						connection_teardown(module);
						MESSAGE_QUEUE_destroy(module->outgoing_messages);
						Lock_Deinit(module->handle_lock);
						free(module);
						module = NULL;
					}
					else
					{
						THREAD_CONTROL default_thread =
						{
							NULL,
							NULL,
							0
						};
						module->broker = broker;
						module->remote_message_wait = config->remote_message_wait;
						module->message_receive_thread = default_thread;
						module->message_send_thread = default_thread;
						module->control_thread = default_thread;
						module->async_create_thread = default_thread;
						module->lifecyle_model = config->lifecycle_model;

						/*Codes_SRS_OUTPROCESS_MODULE_17_041: [ This function shall intitialize a lock for each thread for thread management. ]*/
						if ((module->message_receive_thread.thread_lock = Lock_Init()) == NULL)
						{
							connection_teardown(module);
							MESSAGE_QUEUE_destroy(module->outgoing_messages);
							Lock_Deinit(module->handle_lock);
							free(module);
							module = NULL;
						}
						else if ((module->control_thread.thread_lock = Lock_Init()) == NULL)
						{
							connection_teardown(module);
							MESSAGE_QUEUE_destroy(module->outgoing_messages);
							Lock_Deinit(module->message_receive_thread.thread_lock);
							Lock_Deinit(module->handle_lock);
							free(module);
							module = NULL;
						}
						else if ((module->async_create_thread.thread_lock = Lock_Init()) == NULL)
						{
							connection_teardown(module);
							MESSAGE_QUEUE_destroy(module->outgoing_messages);
							Lock_Deinit(module->control_thread.thread_lock);
							Lock_Deinit(module->message_receive_thread.thread_lock);
							Lock_Deinit(module->handle_lock);
							free(module);
							module = NULL;
						}
						else if ((module->message_send_thread.thread_lock = Lock_Init()) == NULL)
						{
							connection_teardown(module);
							MESSAGE_QUEUE_destroy(module->outgoing_messages);
							Lock_Deinit(module->async_create_thread.thread_lock);
							Lock_Deinit(module->control_thread.thread_lock);
							Lock_Deinit(module->message_receive_thread.thread_lock);
							Lock_Deinit(module->handle_lock);
							free(module);
							module = NULL;
						}
						else if (save_strings(module, config) != 0)
						{
							connection_teardown(module);
							MESSAGE_QUEUE_destroy(module->outgoing_messages);
							Lock_Deinit(module->async_create_thread.thread_lock);
							Lock_Deinit(module->control_thread.thread_lock);
							Lock_Deinit(module->message_receive_thread.thread_lock);
							Lock_Deinit(module->message_send_thread.thread_lock);
							Lock_Deinit(module->handle_lock);
							free(module);
							module = NULL;
						}
						else
						{
							/*Codes_SRS_OUTPROCESS_MODULE_17_014: [ This function shall wait for a Create Response on the control channel. ]*/
							if (ThreadAPI_Create(&(module->async_create_thread.thread_handle), outprocessCreate, module) != THREADAPI_OK)
							{
								/*Codes_SRS_OUTPROCESS_MODULE_17_016: [ If any step in the creation fails, this function shall deallocate all resources and return NULL. ]*/

								LogError("failed to spawn a thread");
								module->async_create_thread.thread_handle = NULL;
								connection_teardown(module);
								delete_strings(module);
								MESSAGE_QUEUE_destroy(module->outgoing_messages);
								Lock_Deinit(module->async_create_thread.thread_lock);
								Lock_Deinit(module->control_thread.thread_lock);
								Lock_Deinit(module->message_receive_thread.thread_lock);
								Lock_Deinit(module->message_send_thread.thread_lock);
								Lock_Deinit(module->handle_lock);
								free(module);
								module = NULL;
							}
							else
							{
								int thread_result = -1;
								if (module->lifecyle_model == OUTPROCESS_LIFECYCLE_SYNC)
								{
									if (ThreadAPI_Join(module->async_create_thread.thread_handle, &thread_result) != THREADAPI_OK)
									{
										/*Codes_SRS_OUTPROCESS_MODULE_17_016: [ If any step in the creation fails, this function shall deallocate all resources and return NULL. ]*/
										LogError("Async create thread failed result=[%d]", thread_result);
										thread_result = -1;
									}
									else
									{
										/*Codes_SRS_OUTPROCESS_MODULE_17_015: [ This function shall expect a successful result from the Create Response to consider the module creation a success. ]*/
										// async thread is done.
									}
									module->async_create_thread.thread_handle = NULL;
								}
								else
								{
									thread_result = 1;
								}
								if (thread_result < 0)
								{
									/*Codes_SRS_OUTPROCESS_MODULE_17_016: [ If any step in the creation fails, this function shall deallocate all resources and return NULL. ]*/
									connection_teardown(module);
									delete_strings(module);
									MESSAGE_QUEUE_destroy(module->outgoing_messages);
									Lock_Deinit(module->async_create_thread.thread_lock);
									Lock_Deinit(module->control_thread.thread_lock);
									Lock_Deinit(module->message_receive_thread.thread_lock);
									Lock_Deinit(module->message_send_thread.thread_lock);
									Lock_Deinit(module->handle_lock);
									free(module);
									module = NULL;
								}
							}
						}
					}
				}
			}
		}
	}
	return module;
}