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