xt_core_bool_t xt_net_client_system_send_message (xt_net_client_system_t *client, xt_core_message_t *message) { xt_core_bool_t success; if (ensure_client_is_connected(client)) { pthread_mutex_lock(&client->messaging_mutex); { if (xt_net_post_system_send_message(client->post, message)) { success = xt_core_bool_true; xt_net_exchange_send_and_receive_messages(client->exchange); if (xt_net_post_system_is_socket_closed(client->post)) { client->server_socket_closed = xt_core_bool_true; if (!handle_disconnect(client)) { xt_core_log_trace(client->log, "xnet", "handle_disconnect"); } } } else { success = xt_core_bool_false; xt_core_log_trace(client->log, "xnet", "x_net_post_send_message"); } } pthread_mutex_unlock(&client->messaging_mutex); } else { success = xt_core_bool_false; xt_core_log_trace(client->log, "xnet", "ensure_client_is_connected"); } return success; }
xt_core_message_t *receive_message(xt_net_client_system_t *client) { xt_core_message_t *message; if (ensure_client_is_connected(client)) { pthread_mutex_lock(&client->messaging_mutex); { xt_net_exchange_send_and_receive_messages(client->exchange); message = xt_net_post_system_receive_message(client->post); if (xt_net_post_system_is_socket_closed(client->post)) { client->server_socket_closed = xt_core_bool_true; if (!handle_disconnect(client)) { xt_core_log_trace(client->log, "xnet", "handle_disconnect"); } } } pthread_mutex_unlock(&client->messaging_mutex); } else { message = NULL; xt_core_log_trace(client->log, "xnet", "ensure_client_is_connected"); } return message; }
ta_identity_t *ta_identity_create(char *name, xt_core_log_t *log) { assert(name); assert(log); ta_identity_t *identity; xt_core_bool_t so_far_so_good; identity = malloc(sizeof *identity); if (identity) { identity->log = log; identity->phrases_qutex = NULL; identity->phrases = NULL; identity->name = xt_core_string_copy(name); if (identity->name) { so_far_so_good = xt_core_bool_true; } else { so_far_so_good = xt_core_bool_false; xt_core_log_trace(log, " ta ", "xt_core_string_copy"); } } else { so_far_so_good = xt_core_bool_false; xt_core_log_trace(log, " ta ", "malloc"); } if (so_far_so_good) { identity->phrases = xt_case_list_create(ta_phrase_compare, ta_phrase_copy, ta_phrase_destroy); if (identity->phrases) { so_far_so_good = xt_core_bool_true; xt_case_list_set_size_limit(identity->phrases, MAX_PHRASES_SIZE); } else { so_far_so_good = xt_core_bool_false; xt_core_log_enter(log, " ta ", "xt_case_list_create"); } } if (so_far_so_good) { identity->phrases_qutex = xt_sync_qutex_create(); if (!identity->phrases_qutex) { so_far_so_good = xt_core_bool_false; xt_core_log_enter(log, " ta ", "xt_sync_qutex_create"); } } if (identity && !so_far_so_good) { if (identity->name) { xt_core_string_destroy(identity->name); } if (identity->phrases) { xt_case_list_destroy(identity->phrases); } if (identity->phrases_qutex) { xt_sync_qutex_destroy(identity->phrases_qutex); } free(identity); identity = NULL; } return identity; }
xt_core_bool_t connect_to_server(xt_net_client_system_t *client) { assert(client); xt_core_bool_t success; unsigned short port; success = xt_core_bool_false; for (port = client->server_min_port; (port <= client->server_max_port) && (!success); port++) { client->socket = xt_net_client_socket_create(client->server_ip_address, port); if (client->socket >= 0) { client->server_socket_closed = xt_core_bool_false; client->server_port = port; xt_core_log_enter(client->log, "xnet", "client connected to server on port %i", port); pthread_mutex_lock(&client->messaging_mutex); { client->post = xt_net_post_system_create(client->socket); if (client->post) { if (xt_net_exchange_register_post (client->exchange, client->post)) { success = xt_core_bool_true; } else { xt_core_log_trace(client->log, "xnet", "x_net_exchange_register_post"); xt_net_client_socket_destroy(client->socket); client->server_socket_closed = xt_core_bool_true; xt_net_post_system_destroy(client->post); client->post = NULL; } } else { xt_core_log_trace(client->log, "xnet", "x_net_post_create"); xt_net_client_socket_destroy(client->socket); client->server_socket_closed = xt_core_bool_true; } } pthread_mutex_unlock(&client->messaging_mutex); } else { xt_core_log_enter(client->log, "xnet", "client could not connect to server on port %i", port); } } return success; }
void xt_net_client_system_process_messages(xt_net_client_system_t *client) { xt_core_message_t *message; unsigned long message_type; xt_net_client_system_handle_message_f handler; engine_container_t *engine_container; xt_net_engine_id_t engine_id; handler = NULL; if (ensure_client_is_connected(client)) { while ((message = receive_message(client))) { message_type = xt_core_message_get_type(message); engine_id = xt_core_message_get_engine_id(message); engine_container = *(client->engines_array + engine_id); if (message_type < engine_container->message_handlers_size) { handler = *(engine_container->message_handlers + message_type); if (handler) { (*handler)(client->custom_client_context, message); } } if (!handler) { printf("client has no handler for %s engine's message %lu\n", xt_net_engine_get_name(engine_container->engine_id, client->get_engine_name), message_type); } xt_core_message_destroy(message); } } else { xt_core_log_trace(client->log, "xnet", "ensure_client_is_connected"); } }
xt_core_bool_t xt_net_client_system_register_engine (xt_net_client_system_t *client, xt_net_engine_id_t engine_id, unsigned long message_type_count) { engine_container_t *engine_container; xt_core_bool_t success; unsigned short each_handler; engine_container = malloc(sizeof *engine_container); if (engine_container) { engine_container->engine_id = engine_id; success = xt_core_bool_true; } else { xt_core_log_trace(client->log, "xnet", "malloc"); success = xt_core_bool_false; } if (success) { engine_container->message_handlers_size = message_type_count; engine_container->message_handlers = malloc((sizeof *engine_container->message_handlers) * message_type_count); if (engine_container->message_handlers) { for (each_handler = 0; each_handler < message_type_count; each_handler++) { *(engine_container->message_handlers + each_handler) = NULL; } success = xt_core_bool_true; } else { xt_core_log_trace(client->log, "xnet", "malloc"); success = xt_core_bool_false; } } if (success) { *(client->engines_array + engine_id) = engine_container; if (!xt_case_list_add_last(client->engines, engine_container)) { success = xt_core_bool_false; } } return success; }
ta_identity_t *ta_identity_create_decoy(char *name, xt_core_log_t *log) { assert(name); assert(log); ta_identity_t *identity; identity = malloc(sizeof *identity); if (identity) { identity->log = log; identity->name = xt_core_string_copy(name); if (!identity->name) { xt_core_log_trace(log, " ta ", "xt_core_string_copy"); free(identity); identity = NULL; } } else { xt_core_log_trace(log, " ta ", "malloc"); } return identity; }
xt_case_list_t *ta_identity_listen(ta_identity_t *identity, unsigned long next_phrase_id) { assert(identity); unsigned long i; xt_case_list_t *phrases; ta_phrase_t *phrase; ta_phrase_t *phrase_copy; unsigned long phrases_size; phrases = xt_case_list_create(ta_phrase_compare, ta_phrase_copy, ta_phrase_destroy); if (phrases) { xt_sync_qutex_lock_shared(identity->phrases_qutex); phrases_size = xt_case_list_get_size(identity->phrases); check_range_of_next_phrase_id(&next_phrase_id, phrases_size); for (i = next_phrase_id; i < phrases_size; i++) { phrase = xt_case_list_find_at(identity->phrases, i); assert(phrase); phrase_copy = ta_phrase_copy(phrase); if (phrase_copy) { if (!xt_case_list_add_last(phrases, phrase_copy)) { xt_core_log_trace(identity->log, " ta ", "xt_case_list_add_last"); ta_phrase_destroy(phrase_copy); break; } } else { xt_core_log_trace(identity->log, " ta ", "ta_phrase_copy"); break; } } xt_sync_qutex_unlock_shared(identity->phrases_qutex); } else { xt_core_log_trace(identity->log, " ta ", "xt_case_list_create"); } return phrases; }
xt_core_bool_t handle_disconnect(xt_net_client_system_t *client) { assert(client); xt_core_bool_t success; xt_core_log_enter(client->log, "xnet", "lost connection to server"); if (xt_net_exchange_unregister_post(client->exchange, client->socket)) { success = xt_core_bool_true; xt_net_post_system_destroy(client->post); client->post = NULL; } else { success = xt_core_bool_false; xt_core_log_trace(client->log, "xnet", "x_net_exchange_unregister_post"); } return success; }
xt_net_client_system_t *xt_net_client_system_create (const char *server_ip_address, unsigned short server_min_port, unsigned short server_max_port, xt_net_engine_get_name_f get_engine_name, void *custom_client_context, xt_core_log_t *log) { assert(server_ip_address); xt_net_client_system_t *client; xt_core_bool_t success; unsigned long each_engine_id; xt_core_bool_t messaging_mutex_needs_destroy; xt_core_bool_t connected; messaging_mutex_needs_destroy = xt_core_bool_false; connected = xt_core_bool_false; client = malloc(sizeof *client); if (client) { client->log = log; client->post = NULL; client->get_engine_name = get_engine_name; client->custom_client_context = custom_client_context; client->server_min_port = server_min_port; client->server_max_port = server_max_port; client->server_socket_closed = xt_core_bool_true; for (each_engine_id = 0; each_engine_id < XT_NET_ENGINE_TYPE_COUNT; each_engine_id++) { *(client->engines_array + each_engine_id) = NULL; } xt_net_post_ipost_init(&client->ipost, xt_net_post_system_compare, xt_net_post_system_create, xt_net_post_system_create_decoy, xt_net_post_system_destroy, xt_net_post_system_destroy_decoy, xt_net_post_system_get_last_receive_activity_time, xt_net_post_system_get_socket, xt_net_post_system_get_stats, xt_net_post_system_receive_message, xt_net_post_system_receive_messages, xt_net_post_system_send_message, xt_net_post_system_send_messages, xt_net_post_system_is_socket_closed, xt_net_post_system_mod, xt_net_post_system_compare_equal); success = xt_core_bool_true; } else { success = xt_core_bool_false; xt_core_log_trace(client->log, "xnet", "malloc"); } if (success) { client->server_ip_address = strdup(server_ip_address); if (!client->server_ip_address) { success = xt_core_bool_false; } } if (success) { client->exchange = xt_net_exchange_create(&client->ipost); if (!client->exchange) { success = xt_core_bool_false; } } if (success) { client->engines = xt_case_list_create(XT_CORE_OBJECT_NO_COMPARE_F, XT_CORE_OBJECT_NO_COPY_F, destroy_engine_container); if (!client->engines) { success = xt_core_bool_false; } } if (success) { if (0 == pthread_mutex_init(&client->messaging_mutex, NULL)) { messaging_mutex_needs_destroy = xt_core_bool_true; } else { success = xt_core_bool_false; xt_core_log_trace(client->log, "xnet", "pthread_mutex_init"); } } if (success) { connected = connect_to_server(client); if (!connected) { success = xt_core_bool_false; xt_core_log_trace(client->log, "xnet", "connect_to_server"); } } if (!success && client) { if (connected) { xt_net_client_socket_destroy(client->socket); } if (client->exchange) { xt_net_exchange_destroy(client->exchange); } if (client->server_ip_address) { free(client->server_ip_address); } if (client->engines) { xt_case_list_destroy(client->engines); } if (messaging_mutex_needs_destroy) { pthread_mutex_destroy(&client->messaging_mutex); } free(client); client = NULL; } return client; }