--- /dev/null
+/*
+ * @file ip_session_data_processor.cpp
+ * @brief read and set session ip data from replication area
+ * @brief data to replication area.
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2009 NTT COMWARE Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ **********************************************************************/
+
+#include "ip_session_data_processor.h"
+#include "protocol_module_base.h"
+#include "boost/format.hpp"
+#include "utility.h"
+
+namespace l7vs
+{
+//! constructor
+ip_session_data_processor::ip_session_data_processor(
+ int timeout,
+ ip_replication_data_processor *replication_data_processor,
+ getloglevel_func_type ingetloglevel, logger_func_type inputLogFatal,
+ logger_func_type inputLogError, logger_func_type inputLogWarn,
+ logger_func_type inputLogInfo, logger_func_type inputLogDebug)
+ : timeout(timeout),
+ replication_data_processor(replication_data_processor),
+ getloglevel(ingetloglevel), putLogFatal(inputLogFatal),
+ putLogError(inputLogError), putLogWarn(inputLogWarn),
+ putLogInfo(inputLogInfo), putLogDebug(inputLogDebug)
+{
+ //ctor
+ /*-------- DEBUG LOG --------*/
+ if (unlikely(LOG_LV_DEBUG == getloglevel())) {
+ boost::format formatter("in_function : Constructor ip_session_data_processor::"
+ "ip_session_data_processor( "
+ "int timeout, ip_replication_data_processor* replication_data_processor, "
+ "getloglevel_func_type ingetloglevel, logger_func_type inputLogFatal, "
+ "logger_func_type inputLogError, logger_func_type inputLogWarn, "
+ "logger_func_type inputLogInfo, logger_func_type inputLogDebug) : "
+ "timeout = %d, replication_data_processor = &(%d).");
+ formatter % timeout % static_cast<void *>(replication_data_processor);
+ putLogDebug(600189, formatter.str(), __FILE__, __LINE__);
+ }
+ /*------DEBUG LOG END------*/
+
+ // parameter check
+ if (unlikely(timeout < 0 || replication_data_processor == NULL)) {
+ /*-------- DEBUG LOG --------*/
+ if (unlikely(LOG_LV_DEBUG == getloglevel())) {
+ putLogDebug(600190, "out_function : Constructor ip_session_data_processor::"
+ "ip_session_data_processor(int timeout, "
+ "ip_replication_data_processor* replication_data_processor, "
+ "getloglevel_func_type ingetloglevel, logger_func_type inputLogFatal, "
+ "logger_func_type inputLogError, logger_func_type inputLogWarn, "
+ "logger_func_type inputLogInfo, logger_func_type inputLogDebug)."
+ , __FILE__, __LINE__);
+ }
+ /*------DEBUG LOG END------*/
+
+ throw std::logic_error("invalid parameter value.");
+ }
+
+ /*-------- DEBUG LOG --------*/
+ if (unlikely(LOG_LV_DEBUG == getloglevel())) {
+ putLogDebug(600191, "out_function : Constructor ip_session_data_processor::"
+ "ip_session_data_processor(int timeout, "
+ "ip_replication_data_processor* replication_data_processor, "
+ "getloglevel_func_type ingetloglevel, logger_func_type inputLogFatal, "
+ "logger_func_type inputLogError, logger_func_type inputLogWarn, "
+ "logger_func_type inputLogInfo, logger_func_type inputLogDebug)."
+ , __FILE__, __LINE__);
+ }
+ /*------DEBUG LOG END------*/
+}
+
+//! destructor
+ip_session_data_processor::~ip_session_data_processor()
+{
+ //dtor
+ /*-------- DEBUG LOG --------*/
+ if (unlikely(LOG_LV_DEBUG == getloglevel())) {
+ putLogDebug(600192, "in/out_function : Destructor ip_session_data_processor::"
+ "~ip_session_data_processor().", __FILE__, __LINE__);
+ }
+ /*------DEBUG LOG END------*/
+}
+
+//! get endpoint from session data
+//! @param[in] ip hash
+//! @param[out] endpoint reference
+//! @return 0 : success
+//! @return 1: failed
+//! @return -1:exception
+int ip_session_data_processor::get_endpoint_from_session_data(
+ int ip_hash,
+ boost::asio::ip::tcp::endpoint &endpoint)
+{
+ /*-------- DEBUG LOG --------*/
+ if (unlikely(LOG_LV_DEBUG == getloglevel())) {
+ boost::format formatter("in_function : int ip_session_data_processor::"
+ "get_endpoint_from_session_data(int ip_hash, "
+ "boost::asio::ip::tcp::endpoint& endpoint) : "
+ "ip_hash = %d.");
+ formatter % ip_hash;
+ putLogDebug(600193, formatter.str(), __FILE__, __LINE__);
+ }
+ /*------DEBUG LOG END------*/
+
+ int ret = 0;
+
+ try {
+ boost::asio::ip::tcp::endpoint init_endpoint;
+
+ // ip hash check
+ if (unlikely(ip_hash < 0 || ip_hash >= MAX_IP_SESSION_TBL_SIZE)) {
+ putLogError(600103, "invalid parameter value.", __FILE__, __LINE__);
+ /*-------- DEBUG LOG --------*/
+ if (unlikely(LOG_LV_DEBUG == getloglevel())) {
+ boost::format formatter("out_function : int ip_session_data_processor::"
+ "get_endpoint_from_session_data(int ip_hash, "
+ "boost::asio::ip::tcp::endpoint& endpoint) : return_value = 1.");
+ putLogDebug(600194, formatter.str(), __FILE__, __LINE__);
+ }
+ /*------DEBUG LOG END------*/
+ return 1;
+ }
+
+ // session is not exist
+ if (session_table[ip_hash].rs_endpoint == init_endpoint) {
+ ret = 1;
+ }
+ // session is exist
+ else {
+ // expired time check
+ time_t now;
+ time(&now);
+ if (session_table[ip_hash].last_time == 0 ||
+ timeout == 0 ||
+ now - session_table[ip_hash].last_time <= timeout) {
+ // time in
+ endpoint = session_table[ip_hash].rs_endpoint;
+ } else {
+ // time out
+ ret = 1;
+ }
+ }
+ } catch (const std::exception &e) {
+ std::cerr << "ip_session_data_processor::get_endpoint_from_session_data() : exception: error = " << e.what() << "." << std::endl;
+ boost::format formatter("function : int ip_session_data_processor::"
+ "get_endpoint_from_session_data() : exception : error = %s.");
+ formatter % e.what();
+ putLogError(600104, formatter.str(), __FILE__, __LINE__);
+
+ ret = -1;
+ }
+
+ /*-------- DEBUG LOG --------*/
+ if (unlikely(LOG_LV_DEBUG == getloglevel())) {
+ boost::format formatter("out_function : int ip_session_data_processor::"
+ "get_endpoint_from_session_data(int ip_hash, "
+ "boost::asio::ip::tcp::endpoint& endpoint) : return_value = %d.");
+ formatter % ret;
+ putLogDebug(600195, formatter.str(), __FILE__, __LINE__);
+ }
+ /*------DEBUG LOG END------*/
+
+ return ret;
+}
+
+//! write session data to session table
+//! @param[in] ip hash
+//! @param[in] endpoint reference
+//! @param[in] now time
+//! @return 0 : success
+//! @return 1: failed
+//! @return -1:exception
+int ip_session_data_processor::write_session_data(
+ int ip_hash,
+ const boost::asio::ip::tcp::endpoint &endpoint,
+ time_t now_time)
+{
+ /*-------- DEBUG LOG --------*/
+ if (unlikely(LOG_LV_DEBUG == getloglevel())) {
+ boost::format formatter("in_function : int ip_session_data_processor::"
+ "write_session_data(int ip_hash,"
+ "const boost::asio::ip::tcp::endpoint& endpoint, "
+ "time_t now_time) : ip_hash = %d, now_time = %d.");
+ formatter % ip_hash % now_time;
+ putLogDebug(600196, formatter.str(), __FILE__, __LINE__);
+ }
+ /*------DEBUG LOG END------*/
+
+ boost::asio::ip::tcp::endpoint init_endpoint;
+ ip_replication_temp_data temp_data;
+
+ try {
+ // ip hash check
+ if (unlikely(ip_hash < 0 || ip_hash >= MAX_IP_SESSION_TBL_SIZE)) {
+ putLogError(600105, "invalid parameter value.", __FILE__, __LINE__);
+ /*-------- DEBUG LOG --------*/
+ if (unlikely(LOG_LV_DEBUG == getloglevel())) {
+ boost::format formatter("out_function : int ip_session_data_processor::"
+ "write_session_data(int ip_hash,"
+ "const boost::asio::ip::tcp::endpoint& endpoint, "
+ "time_t now_time) : return_value = 1.");
+ putLogDebug(600197, formatter.str(), __FILE__, __LINE__);
+ }
+ /*------DEBUG LOG END------*/
+ return 1;
+ }
+
+ // write session data to session table
+ session_table[ip_hash].last_time = now_time;
+
+ // set op_code
+ if (endpoint == init_endpoint) {
+ temp_data.op_code = 'U';
+ } else {
+ session_table[ip_hash].rs_endpoint = endpoint;
+ temp_data.op_code = 'A';
+ }
+
+ // add the replication list
+ temp_data.ip_hash = ip_hash;
+ temp_data.last_time = now_time;
+ temp_data.rs_endpoint = endpoint;
+ replication_data_processor->put_into_temp_list(temp_data);
+ /*-------- DEBUG LOG --------*/
+ if (unlikely(LOG_LV_DEBUG == getloglevel())) {
+ std::string buffer;
+ boost::format formatter("function : int ip_session_data_processor::"
+ "write_session_data() : put_into_temp_list() "
+ "--add item ip_hash = %d -- end.");
+ formatter % ip_hash;
+ putLogDebug(600198, formatter.str(), __FILE__, __LINE__);
+ }
+ /*------DEBUG LOG END------*/
+ } catch (const std::exception &e) {
+ std::cerr << "write_session_data exception : error = " << e.what() << "." << std::endl;
+ boost::format formatter("function : int ip_session_data_processor::"
+ "write_session_data() : exception : error = %s.");
+ formatter % e.what();
+ putLogError(600106, formatter.str(), __FILE__, __LINE__);
+
+ /*-------- DEBUG LOG --------*/
+ if (unlikely(LOG_LV_DEBUG == getloglevel())) {
+ putLogDebug(600199, "out_function : int ip_session_data_processor::"
+ "write_session_data(int hash, "
+ "const boost::asio::ip::tcp::endpoint& endpoint, time_t now_time) : "
+ "return_value = -1.", __FILE__, __LINE__);
+ }
+ /*------DEBUG LOG END------*/
+
+ return -1;
+ }
+
+ /*-------- DEBUG LOG --------*/
+ if (unlikely(LOG_LV_DEBUG == getloglevel())) {
+ putLogDebug(600200, "out_function : int ip_session_data_processor::"
+ "write_ip_data(const std::string& ip, "
+ "const boost::asio::ip::tcp::endpoint& endpoint, time_t now_time) : "
+ "return_value = 0.", __FILE__, __LINE__);
+ }
+ /*------DEBUG LOG END------*/
+
+ return 0;
+}
+
+//! read session data from replication area
+//! @param[in] ip_replication_data pointer
+//! @return 0 : success
+//! @return -1:exception
+int ip_session_data_processor::read_session_data_from_replication_area(
+ ip_replication_data *replication_area)
+{
+ /*-------- DEBUG LOG --------*/
+ if (unlikely(LOG_LV_DEBUG == getloglevel())) {
+ boost::format formatter("in_function : int ip_session_data_processor::"
+ "read_session_data_from_replication_area(ip_replication_data* replication_area) : "
+ "replication_area = &(%d).");
+ formatter % static_cast<void *>(replication_area);
+ putLogDebug(600201, formatter.str(), __FILE__, __LINE__);
+ }
+ /*------DEBUG LOG END------*/
+
+ // null check
+ if (replication_area == NULL) {
+ putLogInfo(600001, "Replication area is null.", __FILE__, __LINE__);
+ /*-------- DEBUG LOG --------*/
+ if (unlikely(LOG_LV_DEBUG == getloglevel())) {
+ putLogDebug(600202, "out_function : int ip_session_data_processor::"
+ "read_session_data_from_replication_area("
+ "ip_replication_data* replication_area) : return_value = -1.", __FILE__, __LINE__);
+ }
+ /*------DEBUG LOG END------*/
+ return -1;
+ }
+
+ int ret = 0;
+ try {
+ // restore replication data to session table
+ for (int i = 0; i < MAX_IP_SESSION_TBL_SIZE; ++i) {
+ if (replication_area[i].valid == 1) {
+ boost::asio::ip::tcp::endpoint endpoint(
+ boost::asio::ip::address::from_string(replication_area[i].realserver_ip),
+ replication_area[i].realserver_port);
+ session_table[i].rs_endpoint = endpoint;
+ session_table[i].last_time = replication_area[i].last_time;
+ }
+ }
+ } catch (const std::exception &e) {
+ std::cerr << "ip_session_data_processor::read_session_data_from_replication_area() : "
+ "exception : error = " << e.what() << "." << std::endl;
+ boost::format formatter("function : int ip_session_data_processor::"
+ "read_session_data_from_replication_area() : exception : error = %s.");
+ formatter % e.what();
+ putLogError(600107, formatter.str(), __FILE__, __LINE__);
+
+ ret = -1;
+ }
+
+ /*-------- DEBUG LOG --------*/
+ if (unlikely(LOG_LV_DEBUG == getloglevel())) {
+ boost::format formatter("out_function : int ip_session_data_processor::"
+ "read_session_data_from_replication_area(ip_replication_data* replication_area) : "
+ "return_value = %d.");
+ formatter % ret;
+ putLogDebug(600203, formatter.str(), __FILE__, __LINE__);
+ }
+ /*------DEBUG LOG END------*/
+
+ return ret;
+}
+
+}