OSDN Git Service

trunk整理
[ultramonkey-l7/ultramonkey-l7-v3.git] / l7vsd / module / protocol / ip_session_data_processor.cpp
diff --git a/l7vsd/module/protocol/ip_session_data_processor.cpp b/l7vsd/module/protocol/ip_session_data_processor.cpp
new file mode 100644 (file)
index 0000000..6e67e94
--- /dev/null
@@ -0,0 +1,350 @@
+/*
+ * @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;
+}
+
+}