diff options
Diffstat (limited to 'tools/tcpmon/src/session.c')
-rw-r--r-- | tools/tcpmon/src/session.c | 632 |
1 files changed, 632 insertions, 0 deletions
diff --git a/tools/tcpmon/src/session.c b/tools/tcpmon/src/session.c new file mode 100644 index 0000000..29d4c78 --- /dev/null +++ b/tools/tcpmon/src/session.c @@ -0,0 +1,632 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <axutil_string.h> +#include <axutil_utils.h> +#include <axutil_error.h> +#include <tcpmon_util.h> +#include <axutil_thread.h> +#include <axutil_network_handler.h> +#include <axutil_array_list.h> + +#include "tcpmon_session_local.h" +#include "tcpmon_entry_local.h" +#include "tcpmon_util.h" + +/** + * @brief + */ +typedef struct tcpmon_session_impl +{ + tcpmon_session_t session; + int listen_port; + int target_port; + int test_bit; + int format_bit; + axis2_char_t *target_host; + TCPMON_SESSION_NEW_ENTRY_FUNCT on_new_entry_funct; + TCPMON_SESSION_TRANS_ERROR_FUNCT on_trans_fault_funct; + axutil_array_list_t *entries; + + axis2_bool_t is_running; +} +tcpmon_session_impl_t; + +typedef struct tcpmon_session_server_thread_data +{ + tcpmon_session_impl_t *session_impl; + const axutil_env_t *env; +} +tcpmon_session_server_thread_data_t; + +#define AXIS2_INTF_TO_IMPL(session) \ + ((tcpmon_session_impl_t *) session) +axutil_thread_t *server_thread = NULL; +tcpmon_session_server_thread_data_t *thread_data = NULL; + + +/************************* Function prototypes ********************************/ + +axis2_status_t AXIS2_CALL tcpmon_session_free( + tcpmon_session_t * session, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL tcpmon_session_set_listen_port( + tcpmon_session_t * session, + const axutil_env_t * env, + int listen_port); + +int AXIS2_CALL tcpmon_session_get_listen_port( + tcpmon_session_t * session, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL tcpmon_session_set_target_port( + tcpmon_session_t * session, + const axutil_env_t * env, + int target_port); + +int AXIS2_CALL tcpmon_session_get_target_port( + tcpmon_session_t * session, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL tcpmon_session_set_target_host( + tcpmon_session_t * session, + const axutil_env_t * env, + axis2_char_t * target_host); + +axis2_char_t *AXIS2_CALL tcpmon_session_get_target_host( + tcpmon_session_t * session, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL tcpmon_session_start( + tcpmon_session_t * session, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL tcpmon_session_stop( + tcpmon_session_t * session, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL tcpmon_session_on_new_entry( + tcpmon_session_t * session, + const axutil_env_t * env, + TCPMON_SESSION_NEW_ENTRY_FUNCT on_new_entry_funct); + +axis2_status_t AXIS2_CALL tcpmon_session_on_trans_fault( + tcpmon_session_t * session, + const axutil_env_t * env, + TCPMON_SESSION_TRANS_ERROR_FUNCT on_trans_fault_funct); + +int AXIS2_CALL tcpmon_session_get_test_bit( + tcpmon_session_t * session, + const axutil_env_t * env); + +int AXIS2_CALL tcpmon_session_set_test_bit( + tcpmon_session_t * session, + const axutil_env_t * env, + int test_bit); + +int AXIS2_CALL tcpmon_session_get_format_bit( + tcpmon_session_t * session, + const axutil_env_t * env); + +int AXIS2_CALL tcpmon_session_set_format_bit( + tcpmon_session_t * session, + const axutil_env_t * env, + int format_bit); + +/** internal implementations */ + +static void *AXIS2_THREAD_FUNC server_funct( + axutil_thread_t * thd, + void *data); + +/************************** End of function prototypes ************************/ + +tcpmon_session_t *AXIS2_CALL +tcpmon_session_create( + const axutil_env_t * env) +{ + tcpmon_session_impl_t *session_impl = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + session_impl = (tcpmon_session_impl_t *) AXIS2_MALLOC(env-> + allocator, + sizeof + (tcpmon_session_impl_t)); + + if (!session_impl) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + session_impl->listen_port = -1; + session_impl->target_port = -1; + session_impl->test_bit = -1; + session_impl->format_bit = 0; + session_impl->target_host = NULL; + + session_impl->on_new_entry_funct = NULL; + session_impl->on_trans_fault_funct = NULL; + session_impl->entries = + axutil_array_list_create(env, AXIS2_ARRAY_LIST_DEFAULT_CAPACITY); + + session_impl->session.ops = + AXIS2_MALLOC(env->allocator, sizeof(tcpmon_session_ops_t)); + if (!session_impl->session.ops) + { + tcpmon_session_free(&(session_impl->session), env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + session_impl->is_running = AXIS2_FALSE; + session_impl->session.ops->free = tcpmon_session_free; + session_impl->session.ops->set_test_bit = tcpmon_session_set_test_bit; + session_impl->session.ops->get_test_bit = tcpmon_session_get_test_bit; + session_impl->session.ops->get_format_bit = tcpmon_session_get_format_bit; + session_impl->session.ops->set_format_bit = tcpmon_session_set_format_bit; + session_impl->session.ops->set_listen_port = tcpmon_session_set_listen_port; + session_impl->session.ops->get_listen_port = tcpmon_session_get_listen_port; + session_impl->session.ops->set_target_port = tcpmon_session_set_target_port; + session_impl->session.ops->get_target_port = tcpmon_session_get_target_port; + session_impl->session.ops->set_target_host = tcpmon_session_set_target_host; + session_impl->session.ops->get_target_host = tcpmon_session_get_target_host; + session_impl->session.ops->start = tcpmon_session_start; + session_impl->session.ops->stop = tcpmon_session_stop; + session_impl->session.ops->on_new_entry = tcpmon_session_on_new_entry; + session_impl->session.ops->on_trans_fault = tcpmon_session_on_trans_fault; + + return &(session_impl->session); +} + +/***************************Function implementation****************************/ + +axis2_status_t AXIS2_CALL +tcpmon_session_free( + tcpmon_session_t * session, + const axutil_env_t * env) +{ + tcpmon_session_impl_t *session_impl = NULL; + int entries_size = 0; + tcpmon_entry_t *entry = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + session_impl = AXIS2_INTF_TO_IMPL(session); + + for (entries_size = axutil_array_list_size(session_impl->entries, env) - 1; + entries_size >= 0; entries_size--) + { + TCPMON_ENTRY_FREE(entry, env); + } + axutil_array_list_free(session_impl->entries, env); + + if (session->ops) + { + AXIS2_FREE(env->allocator, session->ops); + session->ops = NULL; + } + + if (session_impl->target_host) + { + AXIS2_FREE(env->allocator, session_impl->target_host); + session_impl->target_host = NULL; + } + + if (session_impl) + { + AXIS2_FREE(env->allocator, session_impl); + session_impl = NULL; + } + + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +tcpmon_session_set_test_bit( + tcpmon_session_t * session, + const axutil_env_t * env, + int test_bit) +{ + tcpmon_session_impl_t *session_impl = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + session_impl = AXIS2_INTF_TO_IMPL(session); + session_impl->test_bit = test_bit; + return AXIS2_SUCCESS; +} + +int AXIS2_CALL +tcpmon_session_get_test_bit( + tcpmon_session_t * session, + const axutil_env_t * env) +{ + tcpmon_session_impl_t *session_impl = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + session_impl = AXIS2_INTF_TO_IMPL(session); + + return session_impl->test_bit; +} + +axis2_status_t AXIS2_CALL +tcpmon_session_set_format_bit( + tcpmon_session_t * session, + const axutil_env_t * env, + int format_bit) +{ + tcpmon_session_impl_t *session_impl = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + session_impl = AXIS2_INTF_TO_IMPL(session); + + session_impl->format_bit = format_bit; + + return AXIS2_SUCCESS; +} + +int AXIS2_CALL +tcpmon_session_get_format_bit( + tcpmon_session_t * session, + const axutil_env_t * env) +{ + tcpmon_session_impl_t *session_impl = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + session_impl = AXIS2_INTF_TO_IMPL(session); + + return session_impl->format_bit; +} + +axis2_status_t AXIS2_CALL +tcpmon_session_set_listen_port( + tcpmon_session_t * session, + const axutil_env_t * env, + int listen_port) +{ + tcpmon_session_impl_t *session_impl = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + session_impl = AXIS2_INTF_TO_IMPL(session); + + session_impl->listen_port = listen_port; + return AXIS2_SUCCESS; +} + +int AXIS2_CALL +tcpmon_session_get_listen_port( + tcpmon_session_t * session, + const axutil_env_t * env) +{ + tcpmon_session_impl_t *session_impl = NULL; + + AXIS2_ENV_CHECK(env, -1); + + session_impl = AXIS2_INTF_TO_IMPL(session); + + return session_impl->listen_port; +} + +axis2_status_t AXIS2_CALL +tcpmon_session_set_target_port( + tcpmon_session_t * session, + const axutil_env_t * env, + int target_port) +{ + tcpmon_session_impl_t *session_impl = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + session_impl = AXIS2_INTF_TO_IMPL(session); + + session_impl->target_port = target_port; + return AXIS2_SUCCESS; +} + +int AXIS2_CALL +tcpmon_session_get_target_port( + tcpmon_session_t * session, + const axutil_env_t * env) +{ + tcpmon_session_impl_t *session_impl = NULL; + + AXIS2_ENV_CHECK(env, -1); + + session_impl = AXIS2_INTF_TO_IMPL(session); + + return session_impl->target_port; +} + +axis2_status_t AXIS2_CALL +tcpmon_session_set_target_host( + tcpmon_session_t * session, + const axutil_env_t * env, + axis2_char_t * target_host) +{ + tcpmon_session_impl_t *session_impl = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + session_impl = AXIS2_INTF_TO_IMPL(session); + + session_impl->target_host = + (axis2_char_t *) axutil_strdup(env, target_host); + return AXIS2_SUCCESS; +} + +axis2_char_t *AXIS2_CALL +tcpmon_session_get_target_host( + tcpmon_session_t * session, + const axutil_env_t * env) +{ + tcpmon_session_impl_t *session_impl = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + session_impl = AXIS2_INTF_TO_IMPL(session); + + return session_impl->target_host; +} + +axis2_status_t AXIS2_CALL +tcpmon_session_start( + tcpmon_session_t * session, + const axutil_env_t * env) +{ + tcpmon_session_impl_t *session_impl = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + session_impl = AXIS2_INTF_TO_IMPL(session); + + thread_data = + (tcpmon_session_server_thread_data_t *) AXIS2_MALLOC(env->allocator, + sizeof + (tcpmon_session_server_thread_data_t)); + thread_data->session_impl = session_impl; + thread_data->env = env; + + session_impl->is_running = AXIS2_TRUE; + server_thread = axutil_thread_pool_get_thread(env->thread_pool, + server_funct, + (void *) thread_data); + if (!server_thread) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Thread creation failed" + "server thread"); + if (session_impl->on_trans_fault_funct) + { + (session_impl->on_trans_fault_funct) (env, + "error in creating the server thread"); + } + } + + axutil_thread_pool_thread_detach(env->thread_pool, server_thread); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +tcpmon_session_stop( + tcpmon_session_t * session, + const axutil_env_t * env) +{ + tcpmon_session_impl_t *session_impl = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + session_impl = AXIS2_INTF_TO_IMPL(session); + session_impl->is_running = AXIS2_FALSE; + + if (server_thread) + { + AXIS2_FREE(env->allocator, server_thread); + server_thread = NULL; + } + if (thread_data) + { + AXIS2_FREE(env->allocator, (tcpmon_session_server_thread_data_t *)thread_data); + thread_data = NULL; + } + + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +tcpmon_session_on_new_entry( + tcpmon_session_t * session, + const axutil_env_t * env, + TCPMON_SESSION_NEW_ENTRY_FUNCT on_new_entry_funct) +{ + tcpmon_session_impl_t *session_impl = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + session_impl = AXIS2_INTF_TO_IMPL(session); + + session_impl->on_new_entry_funct = on_new_entry_funct; + + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +tcpmon_session_on_trans_fault( + tcpmon_session_t * session, + const axutil_env_t * env, + TCPMON_SESSION_TRANS_ERROR_FUNCT on_trans_fault_funct) +{ + tcpmon_session_impl_t *session_impl = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + session_impl = AXIS2_INTF_TO_IMPL(session); + + session_impl->on_trans_fault_funct = on_trans_fault_funct; + return AXIS2_SUCCESS; +} + +/** internal implementations */ +static void *AXIS2_THREAD_FUNC +server_funct( + axutil_thread_t * thd, + void *data) +{ + tcpmon_session_server_thread_data_t *thread_data = (tcpmon_session_server_thread_data_t *)data; + tcpmon_session_impl_t *session_impl = NULL; + const axutil_env_t *env = NULL; + int listen_socket = -1; + int socket = -1; + axutil_thread_t *request_thread = NULL; + tcpmon_entry_request_data_t *request_thread_data = NULL; + + session_impl = thread_data->session_impl; + env = thread_data->env; + + listen_socket = (int)axutil_network_handler_create_server_socket + (env, session_impl->listen_port); + if (-1 == listen_socket) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "error in creating the server socket, " + "port may be already occupied", "create socket"); + if (session_impl->on_trans_fault_funct) + { + (session_impl->on_trans_fault_funct) (env, + "error in creating the server socket, " + "port may be already occupied"); + } + if (thd) + { + AXIS2_FREE(env->allocator, server_thread); + server_thread = NULL; + } + if (data) + { + AXIS2_FREE(env->allocator, (tcpmon_session_server_thread_data_t *)data); + thread_data = NULL; + } + return NULL; + } + while (session_impl->is_running) + { + socket = (int)axutil_network_handler_svr_socket_accept(env, listen_socket); + if (socket == -1) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "error in creating the socket" "create socket"); + if (session_impl->on_trans_fault_funct) + { + (session_impl->on_trans_fault_funct) (env, + "error in creating the socket"); + } + break; + } + + request_thread_data = + (tcpmon_entry_request_data_t *) AXIS2_MALLOC(env->allocator, + sizeof + (tcpmon_entry_request_data_t)); + request_thread_data->env = env; + request_thread_data->socket = socket; + request_thread_data->session = (tcpmon_session_t *) session_impl; + + request_thread = axutil_thread_pool_get_thread(env->thread_pool, + tcpmon_entry_new_entry_funct, + (void *) + request_thread_data); + if (!request_thread) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Thread creation failed" + "request thread"); + if (session_impl->on_trans_fault_funct) + { + (session_impl->on_trans_fault_funct) (env, + "fail in creating the thread"); + } + break; + } + + axutil_thread_pool_thread_detach(env->thread_pool, request_thread); + } + axutil_network_handler_close_socket(env, listen_socket); + if (thd) + { + AXIS2_FREE(env->allocator, server_thread); + server_thread = NULL; + } + if (data) + { + AXIS2_FREE(env->allocator, (tcpmon_session_server_thread_data_t *)data); + thread_data = NULL; + } + return NULL; +} + +/* implementations for protected functions */ + +axis2_status_t +tcpmon_session_add_new_entry( + tcpmon_session_t * session, + const axutil_env_t * env, + tcpmon_entry_t * entry) +{ + tcpmon_session_impl_t *session_impl = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + session_impl = AXIS2_INTF_TO_IMPL(session); + + axutil_array_list_add(session_impl->entries, env, entry); + return AXIS2_SUCCESS; + +} + +TCPMON_SESSION_TRANS_ERROR_FUNCT +tcpmon_session_get_on_trans_fault( + tcpmon_session_t * session, + const axutil_env_t * env) +{ + tcpmon_session_impl_t *session_impl = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + session_impl = AXIS2_INTF_TO_IMPL(session); + + return session_impl->on_trans_fault_funct; +} + +TCPMON_SESSION_NEW_ENTRY_FUNCT +tcpmon_session_get_on_new_entry( + tcpmon_session_t * session, + const axutil_env_t * env) +{ + tcpmon_session_impl_t *session_impl = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + session_impl = AXIS2_INTF_TO_IMPL(session); + + return session_impl->on_new_entry_funct; +} |