| |
| /* |
| * 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; |
| } |