OSDN Git Service

Fix to ignore 'session_cache' bug.
[ultramonkey-l7/sslproxy.git] / src / sslproxysession.cpp
index aed1eac..4bb93e9 100644 (file)
-/*\r
- * @file  sslproxysession.cpp\r
- * @brief module of SSLproxy_session\r
- * @brief SSL handshaking and Connecting.\r
- * @brief Client and Server data read/write.\r
- *\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *\r
- **********************************************************************\r
- *\r
- * Distributed under the Boost Software Licence, Version 1.0\r
- * http://www.boost.org/LICENSE_1_0.txt\r
- *\r
- **********************************************************************/\r
-\r
-#include <sys/syscall.h>       // for SYS_gettid\r
-#include <boost/lexical_cast.hpp>\r
-\r
-#include "sslproxyserver.h"\r
-#include "sslproxysession.h"\r
-\r
-// sslproxy_session constructor\r
-/*!\r
- * SSLproxy_session constructor.\r
- *\r
- * @param[in]  io_service      IO event dispatcher\r
- * @param[in]  context         SSL context\r
- * @param[in]  itr             endpoint iterator\r
- */\r
-sslproxy_session::sslproxy_session(boost::asio::io_service& ioservice,\r
-                                  boost::asio::ssl::context& context,\r
-                                  boost::asio::ip::tcp::resolver::iterator itr)\r
-                                  :\r
-                                  server_socket(ioservice),\r
-                                  client_socket(ioservice, context),\r
-                                  endpoint_iterator(itr),\r
-                                  timer(ioservice),\r
-                                  cancel_time(timeout_sec),\r
-                                  handshaked(false),\r
-                                  istimeout(false),\r
-                                  c_r_event(false),\r
-                                  c_w_event(false),\r
-                                  s_r_event(false),\r
-                                  s_w_event(false),\r
-                                  finishing(false),\r
-                                  cache_timer(ioservice)\r
-{\r
-       /*-------- DEBUG LOG --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 1,\r
-                       "in/out_function : Constructor sslproxy_session::sslproxy_session("\r
-                       "boost::asio::io_service& ioservice, "\r
-                       "boost::asio::ssl::context& context, "\r
-                       "boost::asio::ip::tcp::resolver::iterator itr)");\r
-       }\r
-       /*------ DEBUG LOG END ------*/\r
-       pthread_mutex_init(&client_socket_mutex, NULL);\r
-}\r
-\r
-/*!\r
- * SSLproxy_session destructor.\r
- */\r
-sslproxy_session::~sslproxy_session()\r
-{\r
-       /*-------- DEBUG LOG --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 2,\r
-                       "in/out_function : Destructor sslproxy_session::~sslproxy_session("\r
-                       "void)");\r
-       }\r
-       /*------ DEBUG LOG END ------*/\r
-}\r
-\r
-/*!\r
- * Low level socket getting function.\r
- *\r
- * @return     password string\r
- * @retval     ssl_socket::lowest_layer_type&\r
- */\r
-ssl_socket::lowest_layer_type& sslproxy_session::low_socket()\r
-{\r
-       /*-------- DEBUG LOG --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 3,\r
-                       "in_function : ssl_socket::lowest_layer_type& sslproxy_session::low_socket("\r
-                       "void)");\r
-       }\r
-       /*------ DEBUG LOG END ------*/\r
-\r
-       try {\r
-               ssl_socket::lowest_layer_type& sock = client_socket.lowest_layer();\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 4,\r
-                               "function : ssl_socket::lowest_layer_type& sslproxy_session::low_socket() : "\r
-                               "lowest_layer() END.");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-       \r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 5,\r
-                               "out_function : ssl_socket::lowest_layer_type& sslproxy_session::low_socket("\r
-                               "void)");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-               return sock;\r
-       } catch (std::exception& e) {\r
-               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 1, \r
-                       "Get low level socket error : %s.", e.what());\r
-               throw -1;\r
-       }\r
-}\r
-\r
-/*!\r
- * Get remote endpoint string.\r
- * get client address:port from SSL socket\r
- *\r
- * @param[in]  socket  client SSL socket\r
- * @return     endpoint string\r
- */\r
-std::string sslproxy_session::get_remote_endpoint(ssl_socket& socket)\r
-{\r
-       /*-------- DEBUG LOG --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 6,\r
-                       "in_function : std::string sslproxy_session::get_remote_endpoint("\r
-                       "ssl_socket& socket)");\r
-       }\r
-       /*------ DEBUG LOG END ------*/\r
-\r
-       std::string endpoint_str = "";\r
-       boost::asio::ip::tcp::endpoint endpoint;\r
-       std::string address;\r
-       std::string port;\r
-\r
-       try {\r
-               try {\r
-                       endpoint = socket.lowest_layer().remote_endpoint();\r
-                       /*-------- DEBUG LOG --------*/\r
-                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 7,\r
-                                       "function : std::string sslproxy_session::get_remote_endpoint() : "\r
-                                       "lowest_layer().remote_endpoint() END.");\r
-                       }\r
-                       /*------ DEBUG LOG END ------*/\r
-               } catch (std::exception& e) {\r
-                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 2, \r
-                               "Get remote endpoint from socket error : %s.", e.what());\r
-                       throw -1;\r
-               }\r
-\r
-               try {\r
-                       address = endpoint.address().to_string();\r
-                       /*-------- DEBUG LOG --------*/\r
-                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 8,\r
-                                       "function : std::string sslproxy_session::get_remote_endpoint() : "\r
-                                       "address().to_string() END.");\r
-                       }\r
-                       /*------ DEBUG LOG END ------*/\r
-               } catch (std::exception& e) {\r
-                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 3, \r
-                               "Get address string error : %s.", e.what());\r
-                       throw -1;\r
-               }\r
-\r
-               try {\r
-                       port = boost::lexical_cast<std::string>(endpoint.port());\r
-                       /*-------- DEBUG LOG --------*/\r
-                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 9,\r
-                                       "function : std::string sslproxy_session::get_remote_endpoint() : "\r
-                                       "lexical_cast(port()) END.");\r
-                       }\r
-                       /*------ DEBUG LOG END ------*/\r
-               } catch (std::exception& e) {\r
-                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 4, \r
-                               "Get port string error : %s.", e.what());\r
-                       throw -1;\r
-               }\r
-\r
-               endpoint_str = address + ":" + port;\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 10,\r
-                               "function : std::string sslproxy_session::get_remote_endpoint() : "\r
-                               "Get remote endpoint string END.");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-\r
-       } catch (int e) {\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 11,\r
-                               "function : std::string sslproxy_session::get_remote_endpoint() : "\r
-                               "get_remote_endpoint() error.");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-       }\r
-\r
-       /*-------- DEBUG LOG --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 12,\r
-                       "out_function : std::string sslproxy_session::get_remote_endpoint("\r
-                       "ssl_socket& socket) : "\r
-                       "return value = %s",\r
-                       endpoint_str.c_str());\r
-       }\r
-       /*------ DEBUG LOG END ------*/\r
-       return endpoint_str;\r
-}\r
-\r
-/*!\r
- * Session start function.\r
- * Start async handshake and Set handshake timer\r
- */\r
-void sslproxy_session::start()\r
-{\r
-       /*-------- DEBUG LOG --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 13,\r
-                       "in_function : void sslproxy_session::start(void)");\r
-       }\r
-       /*------ DEBUG LOG END ------*/\r
-\r
-       // Output connection log. (info level)\r
-       if (conn_log_flag == "on") {\r
-               LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_CONNECTION, 1, \r
-                       "Connect from [%s] to [%s]. %s", \r
-                       get_remote_endpoint(client_socket).c_str(), \r
-                       target_endpoint.c_str(), target_id.c_str());\r
-       }\r
-\r
-       try {\r
-               if(sessionTable.end() != sessionTable.find((long)this)) {\r
-                       // Start async handshake and Set handshake handler.\r
-                       client_socket.async_handshake(boost::asio::ssl::stream_base::server,\r
-                                                     boost::bind(&sslproxy_session::handle_handshake,\r
-                                                                 this,\r
-                                                                 boost::asio::placeholders::error));\r
-                       /*-------- DEBUG LOG --------*/\r
-                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 14,\r
-                                       "function : void sslproxy_session::start() : "\r
-                                       "async_handshake() registration END.");\r
-                       }\r
-                       /*------ DEBUG LOG END ------*/\r
-\r
-                       // Set handshake expire time.\r
-                       try {\r
-                               timer.expires_from_now(boost::posix_time::seconds(cancel_time));\r
-                               /*-------- DEBUG LOG --------*/\r
-                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 15,\r
-                                               "function : void sslproxy_session::start() : "\r
-                                               "expires_from_now() END. "\r
-                                               "cancel_time = %d",\r
-                                               cancel_time);\r
-                               }\r
-                               /*------ DEBUG LOG END ------*/\r
-                       } catch (std::exception& e) {\r
-                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 5, \r
-                                       "Set handshake expire time error : %s.", e.what());\r
-                               throw -1;\r
-                       }\r
-\r
-                       // Start timer waiting and Set timer handler.\r
-                       timer.async_wait(boost::bind(&sslproxy_session::cancel,\r
-                                                    this,\r
-                                                    boost::asio::placeholders::error));\r
-                       /*-------- DEBUG LOG --------*/\r
-                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 16,\r
-                                       "function : void sslproxy_session::start() : "\r
-                                       "async_wait() END.");\r
-                       }\r
-                       /*------ DEBUG LOG END ------*/\r
-               }\r
-       } catch (...) {\r
-               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 6, \r
-                       "Exception occured in sslproxy_session::start().");\r
-               destroy_session(this);\r
-       }\r
-\r
-       /*-------- DEBUG LOG --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 17,\r
-                       "outfunction : void sslproxy_session::start(void)");\r
-       }\r
-       /*------ DEBUG LOG END ------*/\r
-}\r
-\r
-/*!\r
- * Handshake timeout handler function.\r
- *\r
- * @param[in]  error   error code\r
- */\r
-void sslproxy_session::cancel(const boost::system::error_code& error)\r
-{\r
-       // Check session is not already delete.\r
-       if(sessionTable.end() != sessionTable.find((long)this)) {\r
-               // Check timout and finishing status.\r
-               if (istimeout || finishing) {\r
-                       destroy_session(this);\r
-               } else {\r
-                       /*-------- DEBUG LOG --------*/\r
-                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 18,\r
-                                       "in_function : void sslproxy_session::cancel("\r
-                                       "const boost::system::error_code& error) : "\r
-                                       "error = %d, handshaked = %d",\r
-                                       error.value(), handshaked);\r
-                       }\r
-                       /*------ DEBUG LOG END ------*/\r
-\r
-                       if (!error) {\r
-                               // Check session is not already delete.\r
-                               if(sessionTable.end() != sessionTable.find((long)this)) {\r
-                                       // Check handshaked.\r
-                                       if (!handshaked) {\r
-                                               // When handshake not finished then timer is timeout.\r
-                                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 7, \r
-                                                       "Handshake timer wait : %d giveup.", cancel_time);\r
-                                               istimeout = true;\r
-                                               client_socket.lowest_layer().cancel();\r
-                                       } else {\r
-                                               // When handshake finished then timer is diable.\r
-                                               /*-------- DEBUG LOG --------*/\r
-                                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 19,\r
-                                                               "function : void sslproxy_session::cancel() : "\r
-                                                               "Handshake timer is cancel.");\r
-                                               }\r
-                                               /*------ DEBUG LOG END ------*/\r
-                                       }\r
-                               }\r
-                       } else {\r
-                               if (error.value() == ECANCELED) {\r
-                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 1, \r
-                                               "Handshake timer operation cancel. Normal END : %s.",\r
-                                               error.message().c_str());\r
-                               } else {\r
-                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 8, \r
-                                               "Handshake timer wait NG : %s.",\r
-                                               error.message().c_str());\r
-                               }\r
-                       }\r
-\r
-                       /*-------- DEBUG LOG --------*/\r
-                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 20,\r
-                                       "out_function : void sslproxy_session::cancel("\r
-                                       "const boost::system::error_code& error)");\r
-                       }\r
-                       /*------ DEBUG LOG END ------*/\r
-               }\r
-       }\r
-}\r
-\r
-/*!\r
- * Session cache expire handler function.\r
- *\r
- * @param[in]  error   error code\r
- */\r
-void sslproxy_session::cache_expire(const boost::system::error_code& error)\r
-{\r
-       // Check session is not already delete.\r
-       if(sessionTable.end() != sessionTable.find((long)this)) {\r
-               if (!error) {\r
-                       // Server event remain.\r
-                       server_socket.cancel();\r
-               } else {\r
-                       if (error.value() == ECANCELED) {\r
-                               LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 8, \r
-                                       "Cache expire operation cancel. Normal END : %s.",\r
-                                       error.message().c_str());\r
-                       } else {\r
-                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 22, \r
-                                       "Cache expire wait NG : %s.",\r
-                                       error.message().c_str());\r
-                       }\r
-               }\r
-\r
-       }\r
-}\r
-\r
-/*!\r
- * Destroy session function.\r
- *\r
- * @param[in]  session session object\r
- */\r
-void sslproxy_session::destroy_session(sslproxy_session* session)\r
-{\r
-       /*-------- DEBUG LOG --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 21,\r
-                       "in_function : void sslproxy_session::destroy_session("\r
-                       "sslproxy_session* session)");\r
-       }\r
-       /*------ DEBUG LOG END ------*/\r
-\r
-       // Check session is not already delete.\r
-       if(sessionTable.end() != sessionTable.find((long)session)) {\r
-               finishing = true;\r
-               if (!c_r_event && !c_w_event && !s_r_event && !s_w_event) {\r
-                       // All event end.\r
-                       pthread_mutex_lock(&sessionTable_mutex);\r
-                       sessionTable.erase((long)session);\r
-                       pthread_mutex_unlock(&sessionTable_mutex);\r
-                       pthread_mutex_lock(&client_socket_mutex);\r
-                       delete session;\r
-               } else {\r
-                       // Event remain.\r
-                       if (c_r_event || c_w_event) {\r
-                               // Client event remain.\r
-                               if (!istimeout) {\r
-                                       client_socket.lowest_layer().cancel();\r
-                               }\r
-                       } else if (s_r_event || s_w_event) {\r
-                               // Server event remain.\r
-                               // Set expire time for session cache.\r
-                               cache_timer.expires_from_now(boost::posix_time::seconds(session_cache_timeout));\r
-                               cache_timer.async_wait(boost::bind(&sslproxy_session::cache_expire,\r
-                                                            this,\r
-                                                            boost::asio::placeholders::error));\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-/*!\r
- * Hnadshake handling function.\r
- * Check hendshake result and Start async connect.\r
- *\r
- * @param[in]  error   error code\r
- */\r
-void sslproxy_session::handle_handshake(const boost::system::error_code& error)\r
-{\r
-       // Check timout and finishing status.\r
-       if (istimeout || finishing) {\r
-               destroy_session(this);\r
-       } else {\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 22,\r
-                               "in_function : void sslproxy_session::handle_handshake("\r
-                               "const boost::system::error_code& error) : "\r
-                               "error = %d, istimeout = %d",\r
-                               error.value(), istimeout);\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-\r
-               try {\r
-                       // Check handshake result.\r
-                       if (!error) {\r
-                               // Connect to server after handshake\r
-                               boost::asio::ip::tcp::resolver::iterator end;\r
-                               if (endpoint_iterator != end) {\r
-                                       // Start async connect\r
-                                       server_socket.async_connect(*endpoint_iterator++,\r
-                                                                   boost::bind(&sslproxy_session::handle_connect,\r
-                                                                               this,\r
-                                                                               boost::asio::placeholders::error));\r
-                                       /*-------- DEBUG LOG --------*/\r
-                                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 23,\r
-                                                       "function : void sslproxy_session::handle_handshake() : "\r
-                                                       "async_connect() registration END.");\r
-                                       }\r
-                                       /*------ DEBUG LOG END ------*/\r
-                               } else {\r
-                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 9, \r
-                                               "Server endpoint is nothing for connect.");\r
-                                       destroy_session(this);\r
-                               }\r
-                       } else {\r
-                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 10, \r
-                                       "Handshaking NG : %s.",\r
-                                       error.message().c_str());\r
-                               destroy_session(this);\r
-                       }\r
-\r
-               } catch (...) {\r
-                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 11, \r
-                               "Exception occured in sslproxy_session::handle_handshake().");\r
-                       destroy_session(this);\r
-               }\r
-\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 24,\r
-                               "out_function : void sslproxy_session::handle_handshake("\r
-                               "const boost::system::error_code& error)");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-       }\r
-}\r
-\r
-/*!\r
- * Connect handling function.\r
- * Check connect result and Start async read client.\r
- *\r
- * @param[in]  error   error code\r
- */\r
-void sslproxy_session::handle_connect(const boost::system::error_code& error)\r
-{\r
-       // Check timout and finishing status.\r
-       if (istimeout || finishing) {\r
-               destroy_session(this);\r
-       } else {\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 25,\r
-                               "in_function : void sslproxy_session::handle_connect("\r
-                               "const boost::system::error_code& error) : "\r
-                               "error = %d, istimeout = %d",\r
-                               error.value(), istimeout);\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-\r
-               try {\r
-                       // Check connect result.\r
-                       if (!error) {\r
-                               handshaked = true;\r
-                               timer.cancel();\r
-                               // Start async read client.\r
-                               c_r_event = true;\r
-                               pthread_mutex_lock(&client_socket_mutex);\r
-                               client_socket.async_read_some(boost::asio::buffer(client_buffer, MAX_BUFFER_SIZE),\r
-                                                             boost::bind(&sslproxy_session::handle_client_read,\r
-                                                                         this,\r
-                                                                         boost::asio::placeholders::error,\r
-                                                                         boost::asio::placeholders::bytes_transferred));\r
-                               pthread_mutex_unlock(&client_socket_mutex);\r
-                               /*-------- DEBUG LOG --------*/\r
-                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 26,\r
-                                               "function : void sslproxy_session::handle_connect() : "\r
-                                               "Client async_read_some() registration END.");\r
-                               }\r
-                               /*------ DEBUG LOG END ------*/\r
-\r
-                               // Start async read server.\r
-                               s_r_event = true;\r
-                               server_socket.async_read_some(boost::asio::buffer(server_buffer, MAX_BUFFER_SIZE),\r
-                                                             boost::bind(&sslproxy_session::handle_server_read,\r
-                                                                         this,\r
-                                                                         boost::asio::placeholders::error,\r
-                                                                         boost::asio::placeholders::bytes_transferred));\r
-                               /*-------- DEBUG LOG --------*/\r
-                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 27,\r
-                                               "function : void sslproxy_session::handle_connect() : "\r
-                                               "Server async_read_some() registration END.");\r
-                               }\r
-                               /*------ DEBUG LOG END ------*/\r
-                       } else {\r
-                               boost::asio::ip::tcp::resolver::iterator end;\r
-                               if (endpoint_iterator != end) {\r
-                                       // Retry connect to server\r
-                                       LOGGER_PUT_LOG_WARN(LOG_CAT_SSLPROXY_SESSION, 1, \r
-                                               "Connecting NG : %s. Retry connect.",\r
-                                               error.message().c_str());\r
-                                       server_socket.async_connect(*endpoint_iterator++,\r
-                                                                   boost::bind(&sslproxy_session::handle_connect,\r
-                                                                               this,\r
-                                                                               boost::asio::placeholders::error));\r
-                                       /*-------- DEBUG LOG --------*/\r
-                                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 28,\r
-                                                       "function : void sslproxy_session::handle_connect() : "\r
-                                                       "async_connect() retry registration END.");\r
-                                       }\r
-                                       /*------ DEBUG LOG END ------*/\r
-                               } else {\r
-                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 12, \r
-                                               "Connecting NG : %s.",\r
-                                               error.message().c_str());\r
-                                       destroy_session(this);\r
-                               }\r
-                       }\r
-               } catch (...) {\r
-                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 13, \r
-                               "Exception occured in void sslproxy_session::handle_connect().");\r
-                       destroy_session(this);\r
-               }\r
-\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 29,\r
-                               "out_function : void sslproxy_session::handle_connect("\r
-                               "const boost::system::error_code& error)");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-       }\r
-}\r
-\r
-/*!\r
- * Client read handling function.\r
- * Check client read result and Start async write server.\r
- *\r
- * @param[in]  error                   error code\r
- * @param[in]  bytes_transferred       transferred data size\r
- */\r
-void sslproxy_session::handle_client_read(const boost::system::error_code& error,\r
-                                         size_t bytes_transferred)\r
-{\r
-       c_r_event = false;\r
-       // Check timout and finishing status.\r
-       if (istimeout || finishing) {\r
-               destroy_session(this);\r
-       } else {\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 30,\r
-                               "in_function : void sslproxy_session::handle_client_read("\r
-                               "const boost::system::error_code& error, "\r
-                               "size_t bytes_transferred) : "\r
-                               "error = %d, bytes_transferred = %d, istimeout = %d",\r
-                               error.value(), (int)bytes_transferred, istimeout);\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-\r
-               try {\r
-                       // Check client read result.\r
-                       if (!error) {\r
-                               // Start async write server.\r
-                               s_w_event = true;\r
-                               boost::asio::async_write(server_socket,\r
-                                                        boost::asio::buffer(client_buffer, bytes_transferred),\r
-                                                        boost::bind(&sslproxy_session::handle_server_write,\r
-                                                                    this,\r
-                                                                    boost::asio::placeholders::error,\r
-                                                                    bytes_transferred));\r
-                               /*-------- DEBUG LOG --------*/\r
-                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 31,\r
-                                               "function : void sslproxy_session::handle_client_read() : "\r
-                                               "Server async_write() registration END.");\r
-                               }\r
-                               /*------ DEBUG LOG END ------*/\r
-                       } else {\r
-                               if (error.value() == boost::asio::error::eof) {\r
-                                       // When End of file. Client data read complete.\r
-                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 2, \r
-                                               "Client data read complete. Normal END : %s.",\r
-                                               error.message().c_str());\r
-                               } else if (error.value() == boost::asio::error::shut_down) {\r
-                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 3, \r
-                                               "Client already shutdown. Normal END : %s.",\r
-                                               error.message().c_str());\r
-                               } else if (error.value() == boost::asio::error::operation_aborted) {\r
-                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 4, \r
-                                               "Client read operation canceled. Normal END : %s.",\r
-                                               error.message().c_str());\r
-                               } else {\r
-                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 14, \r
-                                               "Client read NG : %s.",\r
-                                               error.message().c_str());\r
-                               }\r
-                               destroy_session(this);\r
-                       }\r
-\r
-               } catch (...) {\r
-                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 15, \r
-                               "Exception occured in void sslproxy_session::handle_client_read().");\r
-                       destroy_session(this);\r
-               }\r
-\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 32,\r
-                               "out_function : void sslproxy_session::handle_client_read("\r
-                               "const boost::system::error_code& error, "\r
-                               "size_t bytes_transferred)");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-       }\r
-}\r
-\r
-/*!\r
- * Server write handling function.\r
- * Check server write result and Start async read server.\r
- *\r
- * @param[in]  error                   error code\r
- * @param[in]  bytes_transferred       transferred data size\r
- */\r
-void sslproxy_session::handle_server_write(const boost::system::error_code& error,\r
-                                          size_t bytes_transferred)\r
-{\r
-       s_w_event = false;\r
-       // Check timout and finishing status.\r
-       if (istimeout || finishing) {\r
-               destroy_session(this);\r
-       } else {\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 33,\r
-                               "in_function : void sslproxy_session::handle_server_write("\r
-                               "const boost::system::error_code& error, "\r
-                               "size_t bytes_transferred) : "\r
-                               "error = %d, bytes_transferred = %d, istimeout = %d",\r
-                               error.value(), (int)bytes_transferred, istimeout);\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-\r
-               try {\r
-                       // Check server write result.\r
-                       if (!error) {\r
-                               // Next client data wait, start async read client again.\r
-                               c_r_event = true;\r
-                               pthread_mutex_lock(&client_socket_mutex);\r
-                               client_socket.async_read_some(boost::asio::buffer(client_buffer, MAX_BUFFER_SIZE),\r
-                                                             boost::bind(&sslproxy_session::handle_client_read,\r
-                                                                         this,\r
-                                                                         boost::asio::placeholders::error,\r
-                                                                         boost::asio::placeholders::bytes_transferred));\r
-                               pthread_mutex_unlock(&client_socket_mutex);\r
-                               /*-------- DEBUG LOG --------*/\r
-                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 34,\r
-                                               "function : void sslproxy_session::handle_server_write() : "\r
-                                               "Client async_read_some() registration again END.");\r
-                               }\r
-                               /*------ DEBUG LOG END ------*/\r
-                       } else {\r
-                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 16, \r
-                                       "Server write NG : %s.",\r
-                                       error.message().c_str());\r
-                               destroy_session(this);\r
-                       }\r
-\r
-               } catch (...) {\r
-                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 17, \r
-                               "Exception occured in void sslproxy_session::handle_server_write().");\r
-                       destroy_session(this);\r
-               }\r
-\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 35,\r
-                               "out_function : void sslproxy_session::handle_server_write("\r
-                               "const boost::system::error_code& error, "\r
-                               "size_t bytes_transferred)");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-       }\r
-}\r
-\r
-/*!\r
- * Server read handling function.\r
- * Check server read result and Start async write client.\r
- *\r
- * @param[in]  error                   error code\r
- * @param[in]  bytes_transferred       transferred data size\r
- */\r
-void sslproxy_session::handle_server_read(const boost::system::error_code& error,\r
-                                         size_t bytes_transferred)\r
-{\r
-       s_r_event = false;\r
-       // Check timout and finishing status.\r
-       if (istimeout || finishing) {\r
-               destroy_session(this);\r
-       } else {\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 36,\r
-                               "in_function : void sslproxy_session::handle_server_read("\r
-                               "const boost::system::error_code& error, "\r
-                               "size_t bytes_transferred) : "\r
-                               "error = %d, bytes_transferred = %d, istimeout = %d",\r
-                               error.value(), (int)bytes_transferred, istimeout);\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-\r
-               try {\r
-                       // Check server read result.\r
-                       if (!error) {\r
-                               // Start async write client.\r
-                               c_w_event = true;\r
-                               pthread_mutex_lock(&client_socket_mutex);\r
-                               boost::asio::async_write(client_socket,\r
-                                                        boost::asio::buffer(server_buffer, bytes_transferred),\r
-                                                        boost::bind(&sslproxy_session::handle_client_write,\r
-                                                                    this,\r
-                                                                    boost::asio::placeholders::error,\r
-                                                                    bytes_transferred));\r
-                               pthread_mutex_unlock(&client_socket_mutex);\r
-                               /*-------- DEBUG LOG --------*/\r
-                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 37,\r
-                                               "function : void sslproxy_session::handle_server_read() : "\r
-                                               "Client async_write() registration END.");\r
-                               }\r
-                               /*------ DEBUG LOG END ------*/\r
-                       } else {\r
-                               if (error.value() == boost::asio::error::eof) {\r
-                                       // When End of file. Server data read complete.\r
-                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 5, \r
-                                               "Server data read complete. Normal END : %s.",\r
-                                               error.message().c_str());\r
-                               } else {\r
-                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 18, \r
-                                               "Server read NG : %s.",\r
-                                               error.message().c_str());\r
-                               }\r
-                               destroy_session(this);\r
-                       }\r
-\r
-               } catch (...) {\r
-                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 19, \r
-                               "Exception occured in void sslproxy_session::handle_server_read().");\r
-                       destroy_session(this);\r
-               }\r
-\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 38,\r
-                               "out_function : void sslproxy_session::handle_server_read("\r
-                               "const boost::system::error_code& error, "\r
-                               "size_t bytes_transferred)");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-       }\r
-}\r
-\r
-/*!\r
- * Client write handling function.\r
- * Check client write result and Start async read client.\r
- *\r
- * @param[in]  error                   error code\r
- * @param[in]  bytes_transferred       transferred data size\r
- */\r
-void sslproxy_session::handle_client_write(const boost::system::error_code& error,\r
-                                          size_t bytes_transferred)\r
-{\r
-       c_w_event = false;\r
-       // Check timout and finishing status.\r
-       if (istimeout || finishing) {\r
-               destroy_session(this);\r
-       } else {\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 39,\r
-                               "in_function : void sslproxy_session::handle_client_write("\r
-                               "const boost::system::error_code& error, "\r
-                               "size_t bytes_transferred) : "\r
-                               "error = %d, bytes_transferred = %d, istimeout = %d",\r
-                               error.value(), (int)bytes_transferred, istimeout);\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-\r
-               try {\r
-                       // Check client write result.\r
-                       if (!error) {\r
-                               // Next server data wait, start async read server again.\r
-                               s_r_event = true;\r
-                               server_socket.async_read_some(boost::asio::buffer(server_buffer, MAX_BUFFER_SIZE),\r
-                                                             boost::bind(&sslproxy_session::handle_server_read,\r
-                                                                         this,\r
-                                                                         boost::asio::placeholders::error,\r
-                                                                         boost::asio::placeholders::bytes_transferred));\r
-                               /*-------- DEBUG LOG --------*/\r
-                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 40,\r
-                                               "function : void sslproxy_session::handle_client_write() : "\r
-                                               "Server async_read_some() registration again END.");\r
-                               }\r
-                               /*------ DEBUG LOG END ------*/\r
-                       } else {\r
-                               if (error.value() == boost::asio::error::connection_reset) {\r
-                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 6, \r
-                                               "Reset connection. Normal END : %s.",\r
-                                               error.message().c_str());\r
-                               } else if (error.value() == boost::asio::error::broken_pipe) {\r
-                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 7, \r
-                                               "Pipe broken. Normal END : %s.",\r
-                                               error.message().c_str());\r
-                               } else {\r
-                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 20, \r
-                                               "Client write NG : %s.",\r
-                                               error.message().c_str());\r
-                               }\r
-                               destroy_session(this);\r
-                       }\r
-\r
-               } catch (...) {\r
-                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 21, \r
-                               "Exception occured in void sslproxy_session::handle_client_write().");\r
-                       destroy_session(this);\r
-               }\r
-\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 41,\r
-                               "out_function : void sslproxy_session::handle_client_write("\r
-                               "const boost::system::error_code& error, "\r
-                               "size_t bytes_transferred)");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-       }\r
-}\r
+/*
+ * @file  sslproxysession.cpp
+ * @brief module of SSLproxy_session
+ * @brief SSL handshaking and Connecting.
+ * @brief Client and Server data read/write.
+ *
+ * Copyright (C) 2008  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
+ *
+ **********************************************************************
+ *
+ * Distributed under the Boost Software Licence, Version 1.0
+ * http://www.boost.org/LICENSE_1_0.txt
+ *
+ **********************************************************************/
+
+#include <sys/syscall.h>       // for SYS_gettid
+#include <boost/lexical_cast.hpp>
+
+#include "sslproxyserver.h"
+#include "sslproxysession.h"
+#include "packet_editor.h"
+#include "http_message.h"
+#include "http_request.h"
+#include "http_response.h"
+
+// sslproxy_session constructor
+/*!
+ * SSLproxy_session constructor.
+ *
+ * @param[in]  io_service      IO event dispatcher
+ * @param[in]  context         SSL context
+ * @param[in]  itr             endpoint iterator
+ */
+sslproxy_session::sslproxy_session(boost::asio::io_service& ioservice,
+                                  boost::asio::ssl::context& context,
+                                  boost::asio::ip::tcp::resolver::iterator itr)
+                                  :
+                                  server_socket(ioservice),
+                                  client_socket(ioservice, context),
+                                  endpoint_iterator(itr),
+                                  timer(ioservice),
+                                  cancel_time(timeout_sec),
+                                  handshaked(false),
+                                  istimeout(false),
+                                  c_r_event(false),
+                                  c_w_event(false),
+                                  s_r_event(false),
+                                  s_w_event(false),
+                                  finishing(false),
+                                  cache_timer(ioservice)
+{
+       /*-------- DEBUG LOG --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 1,
+                       "in/out_function : Constructor sslproxy_session::sslproxy_session("
+                       "boost::asio::io_service& ioservice, "
+                       "boost::asio::ssl::context& context, "
+                       "boost::asio::ip::tcp::resolver::iterator itr)");
+       }
+       /*------ DEBUG LOG END ------*/
+       pthread_mutex_init(&client_socket_mutex, NULL);
+}
+
+/*!
+ * SSLproxy_session destructor.
+ */
+sslproxy_session::~sslproxy_session()
+{
+       /*-------- DEBUG LOG --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 2,
+                       "in/out_function : Destructor sslproxy_session::~sslproxy_session("
+                       "void)");
+       }
+       /*------ DEBUG LOG END ------*/
+}
+
+/*!
+ * Low level socket getting function.
+ *
+ * @return     password string
+ * @retval     ssl_socket::lowest_layer_type&
+ */
+ssl_socket::lowest_layer_type& sslproxy_session::low_socket()
+{
+       /*-------- DEBUG LOG --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 3,
+                       "in_function : ssl_socket::lowest_layer_type& sslproxy_session::low_socket("
+                       "void)");
+       }
+       /*------ DEBUG LOG END ------*/
+
+       try {
+               ssl_socket::lowest_layer_type& sock = client_socket.lowest_layer();
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 4,
+                               "function : ssl_socket::lowest_layer_type& sslproxy_session::low_socket() : "
+                               "lowest_layer() END.");
+               }
+               /*------ DEBUG LOG END ------*/
+       
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 5,
+                               "out_function : ssl_socket::lowest_layer_type& sslproxy_session::low_socket("
+                               "void)");
+               }
+               /*------ DEBUG LOG END ------*/
+               return sock;
+       } catch (std::exception& e) {
+               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 1, 
+                       "Get low level socket error : %s.", e.what());
+               throw -1;
+       }
+}
+
+/*!
+ * Get remote endpoint string.
+ * get client address:port from SSL socket
+ *
+ * @param[in]  socket  client SSL socket
+ * @return     endpoint string
+ */
+std::string sslproxy_session::get_remote_endpoint() const
+{
+       /*-------- DEBUG LOG --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 6,
+                       "in_function : std::string sslproxy_session::get_remote_endpoint("
+                       "ssl_socket& socket)");
+       }
+       /*------ DEBUG LOG END ------*/
+
+       std::string endpoint_str = "";
+       boost::asio::ip::tcp::endpoint endpoint;
+       std::string address;
+       std::string port;
+
+       try {
+               try {
+                       endpoint = client_socket.lowest_layer().remote_endpoint();
+                       /*-------- DEBUG LOG --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 7,
+                                       "function : std::string sslproxy_session::get_remote_endpoint() : "
+                                       "lowest_layer().remote_endpoint() END.");
+                       }
+                       /*------ DEBUG LOG END ------*/
+               } catch (std::exception& e) {
+                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 2, 
+                               "Get remote endpoint from socket error : %s.", e.what());
+                       throw -1;
+               }
+
+               try {
+                       address = endpoint.address().to_string();
+                       /*-------- DEBUG LOG --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 8,
+                                       "function : std::string sslproxy_session::get_remote_endpoint() : "
+                                       "address().to_string() END.");
+                       }
+                       /*------ DEBUG LOG END ------*/
+               } catch (std::exception& e) {
+                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 3, 
+                               "Get address string error : %s.", e.what());
+                       throw -1;
+               }
+
+               try {
+                       port = boost::lexical_cast<std::string>(endpoint.port());
+                       /*-------- DEBUG LOG --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 9,
+                                       "function : std::string sslproxy_session::get_remote_endpoint() : "
+                                       "lexical_cast(port()) END.");
+                       }
+                       /*------ DEBUG LOG END ------*/
+               } catch (std::exception& e) {
+                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 4, 
+                               "Get port string error : %s.", e.what());
+                       throw -1;
+               }
+
+               endpoint_str = address + ":" + port;
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 10,
+                               "function : std::string sslproxy_session::get_remote_endpoint() : "
+                               "Get remote endpoint string END.");
+               }
+               /*------ DEBUG LOG END ------*/
+
+       } catch (int e) {
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 11,
+                               "function : std::string sslproxy_session::get_remote_endpoint() : "
+                               "get_remote_endpoint() error.");
+               }
+               /*------ DEBUG LOG END ------*/
+       }
+
+       /*-------- DEBUG LOG --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 12,
+                       "out_function : std::string sslproxy_session::get_remote_endpoint("
+                       "ssl_socket& socket) : "
+                       "return value = %s",
+                       endpoint_str.c_str());
+       }
+       /*------ DEBUG LOG END ------*/
+       return endpoint_str;
+}
+
+/*!
+ * Session start function.
+ * Start async handshake and Set handshake timer
+ */
+void sslproxy_session::start()
+{
+       /*-------- DEBUG LOG --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 13,
+                       "in_function : void sslproxy_session::start(void)");
+       }
+       /*------ DEBUG LOG END ------*/
+
+       // Output connection log. (info level)
+       if (conn_log_flag == "on") {
+               LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_CONNECTION, 1, 
+                       "Connect from [%s] to [%s]. %s", 
+                       get_remote_endpoint().c_str(), 
+                       target_endpoint.c_str(), target_id.c_str());
+       }
+
+       try {
+               if(sessionTable.end() != sessionTable.find((long)this)) {
+                       // Start async handshake and Set handshake handler.
+                       client_socket.async_handshake(boost::asio::ssl::stream_base::server,
+                                                     boost::bind(&sslproxy_session::handle_handshake,
+                                                                 this,
+                                                                 boost::asio::placeholders::error));
+                       /*-------- DEBUG LOG --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 14,
+                                       "function : void sslproxy_session::start() : "
+                                       "async_handshake() registration END.");
+                       }
+                       /*------ DEBUG LOG END ------*/
+
+                       // Set handshake expire time.
+                       try {
+                               timer.expires_from_now(boost::posix_time::seconds(cancel_time));
+                               /*-------- DEBUG LOG --------*/
+                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 15,
+                                               "function : void sslproxy_session::start() : "
+                                               "expires_from_now() END. "
+                                               "cancel_time = %d",
+                                               cancel_time);
+                               }
+                               /*------ DEBUG LOG END ------*/
+                       } catch (std::exception& e) {
+                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 5, 
+                                       "Set handshake expire time error : %s.", e.what());
+                               throw -1;
+                       }
+
+                       // Start timer waiting and Set timer handler.
+                       timer.async_wait(boost::bind(&sslproxy_session::cancel,
+                                                    this,
+                                                    boost::asio::placeholders::error));
+                       /*-------- DEBUG LOG --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 16,
+                                       "function : void sslproxy_session::start() : "
+                                       "async_wait() END.");
+                       }
+                       /*------ DEBUG LOG END ------*/
+               }
+       } catch (...) {
+               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 6, 
+                       "Exception occured in sslproxy_session::start().");
+               destroy_session(this);
+       }
+
+       /*-------- DEBUG LOG --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 17,
+                       "outfunction : void sslproxy_session::start(void)");
+       }
+       /*------ DEBUG LOG END ------*/
+}
+
+/*!
+ * Handshake timeout handler function.
+ *
+ * @param[in]  error   error code
+ */
+void sslproxy_session::cancel(const boost::system::error_code& error)
+{
+       // Check session is not already delete.
+       if(sessionTable.end() != sessionTable.find((long)this)) {
+               // Check timout and finishing status.
+               if (istimeout || finishing) {
+                       destroy_session(this);
+               } else {
+                       /*-------- DEBUG LOG --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 18,
+                                       "in_function : void sslproxy_session::cancel("
+                                       "const boost::system::error_code& error) : "
+                                       "error = %d, handshaked = %d",
+                                       error.value(), handshaked);
+                       }
+                       /*------ DEBUG LOG END ------*/
+
+                       if (!error) {
+                               // Check session is not already delete.
+                               if(sessionTable.end() != sessionTable.find((long)this)) {
+                                       // Check handshaked.
+                                       if (!handshaked) {
+                                               // When handshake not finished then timer is timeout.
+                                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 7, 
+                                                       "Handshake timer wait : %d giveup.", cancel_time);
+                                               istimeout = true;
+                                               client_socket.lowest_layer().cancel();
+                                       } else {
+                                               // When handshake finished then timer is diable.
+                                               /*-------- DEBUG LOG --------*/
+                                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 19,
+                                                               "function : void sslproxy_session::cancel() : "
+                                                               "Handshake timer is cancel.");
+                                               }
+                                               /*------ DEBUG LOG END ------*/
+                                       }
+                               }
+                       } else {
+                               if (error.value() == ECANCELED) {
+                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 1, 
+                                               "Handshake timer operation cancel. Normal END : %s.",
+                                               error.message().c_str());
+                               } else {
+                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 8, 
+                                               "Handshake timer wait NG : %s.",
+                                               error.message().c_str());
+                               }
+                       }
+
+                       /*-------- DEBUG LOG --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 20,
+                                       "out_function : void sslproxy_session::cancel("
+                                       "const boost::system::error_code& error)");
+                       }
+                       /*------ DEBUG LOG END ------*/
+               }
+       }
+}
+
+/*!
+ * Session cache expire handler function.
+ *
+ * @param[in]  error   error code
+ */
+void sslproxy_session::cache_expire(const boost::system::error_code& error)
+{
+       // Check session is not already delete.
+       if(sessionTable.end() != sessionTable.find((long)this)) {
+               if (!error) {
+                       // Server event remain.
+                       server_socket.cancel();
+               } else {
+                       if (error.value() == ECANCELED) {
+                               LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 8, 
+                                       "Cache expire operation cancel. Normal END : %s.",
+                                       error.message().c_str());
+                       } else {
+                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 22, 
+                                       "Cache expire wait NG : %s.",
+                                       error.message().c_str());
+                       }
+               }
+
+       }
+}
+
+/*!
+ * Destroy session function.
+ *
+ * @param[in]  session session object
+ */
+void sslproxy_session::destroy_session(sslproxy_session* session)
+{
+       /*-------- DEBUG LOG --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 21,
+                       "in_function : void sslproxy_session::destroy_session("
+                       "sslproxy_session* session)");
+       }
+       /*------ DEBUG LOG END ------*/
+
+       // Check session is not already delete.
+       if(sessionTable.end() != sessionTable.find((long)session)) {
+               finishing = true;
+               if (!c_r_event && !c_w_event && !s_r_event && !s_w_event) {
+                       // All event end.
+                       pthread_mutex_lock(&sessionTable_mutex);
+                       sessionTable.erase((long)session);
+                       pthread_mutex_unlock(&sessionTable_mutex);
+                       pthread_mutex_lock(&client_socket_mutex);
+                       delete session;
+               } else {
+                       // Event remain.
+                       if (c_r_event || c_w_event) {
+                               // Client event remain.
+                               if (!istimeout) {
+                                       client_socket.lowest_layer().cancel();
+                               }
+                       } else if (s_r_event || s_w_event) {
+                               // Server event remain.
+                               if (session_cache_mode == SSL_SESS_CACHE_OFF) {
+                                       server_socket.cancel();
+                               } else {
+                                       // Set expire time for session cache.
+                                       cache_timer.expires_from_now(boost::posix_time::seconds(session_cache_timeout));
+                                       cache_timer.async_wait(boost::bind(&sslproxy_session::cache_expire,
+                                                            this,
+                                                            boost::asio::placeholders::error));
+                               }
+                       }
+               }
+       }
+}
+
+/*!
+ * Hnadshake handling function.
+ * Check hendshake result and Start async connect.
+ *
+ * @param[in]  error   error code
+ */
+void sslproxy_session::handle_handshake(const boost::system::error_code& error)
+{
+       // Check timout and finishing status.
+       if (istimeout || finishing) {
+               destroy_session(this);
+       } else {
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 22,
+                               "in_function : void sslproxy_session::handle_handshake("
+                               "const boost::system::error_code& error) : "
+                               "error = %d, istimeout = %d",
+                               error.value(), istimeout);
+               }
+               /*------ DEBUG LOG END ------*/
+
+               try {
+                       // Check handshake result.
+                       if (!error) {
+                               // Connect to server after handshake
+                               boost::asio::ip::tcp::resolver::iterator end;
+                               if (endpoint_iterator != end) {
+                                       // Start async connect
+                                       server_socket.async_connect(*endpoint_iterator++,
+                                                                   boost::bind(&sslproxy_session::handle_connect,
+                                                                               this,
+                                                                               boost::asio::placeholders::error));
+                                       /*-------- DEBUG LOG --------*/
+                                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 23,
+                                                       "function : void sslproxy_session::handle_handshake() : "
+                                                       "async_connect() registration END.");
+                                       }
+                                       /*------ DEBUG LOG END ------*/
+                               } else {
+                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 9, 
+                                               "Server endpoint is nothing for connect.");
+                                       destroy_session(this);
+                               }
+                       } else {
+                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 10, 
+                                       "Handshaking NG : %s.",
+                                       error.message().c_str());
+                               destroy_session(this);
+                       }
+
+               } catch (...) {
+                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 11, 
+                               "Exception occured in sslproxy_session::handle_handshake().");
+                       destroy_session(this);
+               }
+
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 24,
+                               "out_function : void sslproxy_session::handle_handshake("
+                               "const boost::system::error_code& error)");
+               }
+               /*------ DEBUG LOG END ------*/
+       }
+}
+
+/*!
+ * Connect handling function.
+ * Check connect result and Start async read client.
+ *
+ * @param[in]  error   error code
+ */
+void sslproxy_session::handle_connect(const boost::system::error_code& error)
+{
+       // Check timout and finishing status.
+       if (istimeout || finishing) {
+               destroy_session(this);
+       } else {
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 25,
+                               "in_function : void sslproxy_session::handle_connect("
+                               "const boost::system::error_code& error) : "
+                               "error = %d, istimeout = %d",
+                               error.value(), istimeout);
+               }
+               /*------ DEBUG LOG END ------*/
+
+               try {
+                       // Check connect result.
+                       if (!error) {
+                               handshaked = true;
+                               timer.cancel();
+                               // Start async read client.
+                               c_r_event = true;
+                               pthread_mutex_lock(&client_socket_mutex);
+                               client_socket.async_read_some(boost::asio::buffer(client_buffer, MAX_READ_SIZE),
+                                                             boost::bind(&sslproxy_session::handle_client_read,
+                                                                         this,
+                                                                         boost::asio::placeholders::error,
+                                                                         boost::asio::placeholders::bytes_transferred));
+                               pthread_mutex_unlock(&client_socket_mutex);
+                               /*-------- DEBUG LOG --------*/
+                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 26,
+                                               "function : void sslproxy_session::handle_connect() : "
+                                               "Client async_read_some() registration END.");
+                               }
+                               /*------ DEBUG LOG END ------*/
+
+                               // Start async read server.
+                               s_r_event = true;
+                               server_socket.async_read_some(boost::asio::buffer(server_buffer, MAX_READ_SIZE),
+                                                             boost::bind(&sslproxy_session::handle_server_read,
+                                                                         this,
+                                                                         boost::asio::placeholders::error,
+                                                                         boost::asio::placeholders::bytes_transferred));
+                               /*-------- DEBUG LOG --------*/
+                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 27,
+                                               "function : void sslproxy_session::handle_connect() : "
+                                               "Server async_read_some() registration END.");
+                               }
+                               /*------ DEBUG LOG END ------*/
+                       } else {
+                               boost::asio::ip::tcp::resolver::iterator end;
+                               if (endpoint_iterator != end) {
+                                       // Retry connect to server
+                                       LOGGER_PUT_LOG_WARN(LOG_CAT_SSLPROXY_SESSION, 1, 
+                                               "Connecting NG : %s. Retry connect.",
+                                               error.message().c_str());
+                                       server_socket.async_connect(*endpoint_iterator++,
+                                                                   boost::bind(&sslproxy_session::handle_connect,
+                                                                               this,
+                                                                               boost::asio::placeholders::error));
+                                       /*-------- DEBUG LOG --------*/
+                                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 28,
+                                                       "function : void sslproxy_session::handle_connect() : "
+                                                       "async_connect() retry registration END.");
+                                       }
+                                       /*------ DEBUG LOG END ------*/
+                               } else {
+                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 12, 
+                                               "Connecting NG : %s.",
+                                               error.message().c_str());
+                                       destroy_session(this);
+                               }
+                       }
+               } catch (...) {
+                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 13, 
+                               "Exception occured in void sslproxy_session::handle_connect().");
+                       destroy_session(this);
+               }
+
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 29,
+                               "out_function : void sslproxy_session::handle_connect("
+                               "const boost::system::error_code& error)");
+               }
+               /*------ DEBUG LOG END ------*/
+       }
+}
+
+/*!
+ * Client read handling function.
+ * Check client read result and Start async write server.
+ *
+ * @param[in]  error                   error code
+ * @param[in]  bytes_transferred       transferred data size
+ */
+void sslproxy_session::handle_client_read(const boost::system::error_code& error,
+                                         size_t bytes_transferred)
+{
+       c_r_event = false;
+       // Check timout and finishing status.
+       if (istimeout || finishing) {
+               destroy_session(this);
+       } else {
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 30,
+                               "in_function : void sslproxy_session::handle_client_read("
+                               "const boost::system::error_code& error, "
+                               "size_t bytes_transferred) : "
+                               "error = %d, bytes_transferred = %d, istimeout = %d",
+                               error.value(), (int)bytes_transferred, istimeout);
+               }
+               /*------ DEBUG LOG END ------*/
+
+               try {
+                       // Check client read result.
+                       if (!error) {
+                               // Edit client message if necessary.
+                               if (::client_packet_edit)
+                                       edit_client_message(bytes_transferred);
+                               // Start async write server.
+                               s_w_event = true;
+                               boost::asio::async_write(server_socket,
+                                                        boost::asio::buffer(client_buffer, bytes_transferred),
+                                                        boost::bind(&sslproxy_session::handle_server_write,
+                                                                    this,
+                                                                    boost::asio::placeholders::error,
+                                                                    bytes_transferred));
+                               /*-------- DEBUG LOG --------*/
+                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 31,
+                                               "function : void sslproxy_session::handle_client_read() : "
+                                               "Server async_write() registration END.");
+                               }
+                               /*------ DEBUG LOG END ------*/
+                       } else {
+                               if (error.value() == boost::asio::error::eof) {
+                                       // When End of file. Client data read complete.
+                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 2, 
+                                               "Client data read complete. Normal END : %s.",
+                                               error.message().c_str());
+                               } else if (error.value() == boost::asio::error::shut_down) {
+                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 3, 
+                                               "Client already shutdown. Normal END : %s.",
+                                               error.message().c_str());
+                               } else if (error.value() == boost::asio::error::operation_aborted) {
+                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 4, 
+                                               "Client read operation canceled. Normal END : %s.",
+                                               error.message().c_str());
+                               } else {
+                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 14, 
+                                               "Client read NG : %s.",
+                                               error.message().c_str());
+                               }
+                               destroy_session(this);
+                       }
+
+               } catch (...) {
+                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 15, 
+                               "Exception occured in void sslproxy_session::handle_client_read().");
+                       destroy_session(this);
+               }
+
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 32,
+                               "out_function : void sslproxy_session::handle_client_read("
+                               "const boost::system::error_code& error, "
+                               "size_t bytes_transferred)");
+               }
+               /*------ DEBUG LOG END ------*/
+       }
+}
+
+/*!
+ * Server write handling function.
+ * Check server write result and Start async read server.
+ *
+ * @param[in]  error                   error code
+ * @param[in]  bytes_transferred       transferred data size
+ */
+void sslproxy_session::handle_server_write(const boost::system::error_code& error,
+                                          size_t bytes_transferred)
+{
+       s_w_event = false;
+       // Check timout and finishing status.
+       if (istimeout || finishing) {
+               destroy_session(this);
+       } else {
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 33,
+                               "in_function : void sslproxy_session::handle_server_write("
+                               "const boost::system::error_code& error, "
+                               "size_t bytes_transferred) : "
+                               "error = %d, bytes_transferred = %d, istimeout = %d",
+                               error.value(), (int)bytes_transferred, istimeout);
+               }
+               /*------ DEBUG LOG END ------*/
+
+               try {
+                       // Check server write result.
+                       if (!error) {
+                               // Next client data wait, start async read client again.
+                               c_r_event = true;
+                               pthread_mutex_lock(&client_socket_mutex);
+                               client_socket.async_read_some(boost::asio::buffer(client_buffer, MAX_READ_SIZE),
+                                                             boost::bind(&sslproxy_session::handle_client_read,
+                                                                         this,
+                                                                         boost::asio::placeholders::error,
+                                                                         boost::asio::placeholders::bytes_transferred));
+                               pthread_mutex_unlock(&client_socket_mutex);
+                               /*-------- DEBUG LOG --------*/
+                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 34,
+                                               "function : void sslproxy_session::handle_server_write() : "
+                                               "Client async_read_some() registration again END.");
+                               }
+                               /*------ DEBUG LOG END ------*/
+                       } else {
+                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 16, 
+                                       "Server write NG : %s.",
+                                       error.message().c_str());
+                               destroy_session(this);
+                       }
+
+               } catch (...) {
+                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 17, 
+                               "Exception occured in void sslproxy_session::handle_server_write().");
+                       destroy_session(this);
+               }
+
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 35,
+                               "out_function : void sslproxy_session::handle_server_write("
+                               "const boost::system::error_code& error, "
+                               "size_t bytes_transferred)");
+               }
+               /*------ DEBUG LOG END ------*/
+       }
+}
+
+/*!
+ * Server read handling function.
+ * Check server read result and Start async write client.
+ *
+ * @param[in]  error                   error code
+ * @param[in]  bytes_transferred       transferred data size
+ */
+void sslproxy_session::handle_server_read(const boost::system::error_code& error,
+                                         size_t bytes_transferred)
+{
+       s_r_event = false;
+       // Check timout and finishing status.
+       if (istimeout || finishing) {
+               destroy_session(this);
+       } else {
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 36,
+                               "in_function : void sslproxy_session::handle_server_read("
+                               "const boost::system::error_code& error, "
+                               "size_t bytes_transferred) : "
+                               "error = %d, bytes_transferred = %d, istimeout = %d",
+                               error.value(), (int)bytes_transferred, istimeout);
+               }
+               /*------ DEBUG LOG END ------*/
+
+               try {
+                       // Check server read result.
+                       if (!error) {
+                               // Edit client message if necessary.
+                               if (::server_packet_edit)
+                                       edit_server_message(bytes_transferred);
+                               // Start async write client.
+                               c_w_event = true;
+                               pthread_mutex_lock(&client_socket_mutex);
+                               boost::asio::async_write(client_socket,
+                                                        boost::asio::buffer(server_buffer, bytes_transferred),
+                                                        boost::bind(&sslproxy_session::handle_client_write,
+                                                                    this,
+                                                                    boost::asio::placeholders::error,
+                                                                    bytes_transferred));
+                               pthread_mutex_unlock(&client_socket_mutex);
+                               /*-------- DEBUG LOG --------*/
+                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 37,
+                                               "function : void sslproxy_session::handle_server_read() : "
+                                               "Client async_write() registration END.");
+                               }
+                               /*------ DEBUG LOG END ------*/
+                       } else {
+                               if (error.value() == boost::asio::error::eof) {
+                                       // When End of file. Server data read complete.
+                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 5, 
+                                               "Server data read complete. Normal END : %s.",
+                                               error.message().c_str());
+                               } else {
+                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 18, 
+                                               "Server read NG : %s.",
+                                               error.message().c_str());
+                               }
+                               destroy_session(this);
+                       }
+
+               } catch (...) {
+                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 19, 
+                               "Exception occured in void sslproxy_session::handle_server_read().");
+                       destroy_session(this);
+               }
+
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 38,
+                               "out_function : void sslproxy_session::handle_server_read("
+                               "const boost::system::error_code& error, "
+                               "size_t bytes_transferred)");
+               }
+               /*------ DEBUG LOG END ------*/
+       }
+}
+
+/*!
+ * Client write handling function.
+ * Check client write result and Start async read client.
+ *
+ * @param[in]  error                   error code
+ * @param[in]  bytes_transferred       transferred data size
+ */
+void sslproxy_session::handle_client_write(const boost::system::error_code& error,
+                                          size_t bytes_transferred)
+{
+       c_w_event = false;
+       // Check timout and finishing status.
+       if (istimeout || finishing) {
+               destroy_session(this);
+       } else {
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 39,
+                               "in_function : void sslproxy_session::handle_client_write("
+                               "const boost::system::error_code& error, "
+                               "size_t bytes_transferred) : "
+                               "error = %d, bytes_transferred = %d, istimeout = %d",
+                               error.value(), (int)bytes_transferred, istimeout);
+               }
+               /*------ DEBUG LOG END ------*/
+
+               try {
+                       // Check client write result.
+                       if (!error) {
+                               // Next server data wait, start async read server again.
+                               s_r_event = true;
+                               server_socket.async_read_some(boost::asio::buffer(server_buffer, MAX_READ_SIZE),
+                                                             boost::bind(&sslproxy_session::handle_server_read,
+                                                                         this,
+                                                                         boost::asio::placeholders::error,
+                                                                         boost::asio::placeholders::bytes_transferred));
+                               /*-------- DEBUG LOG --------*/
+                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 40,
+                                               "function : void sslproxy_session::handle_client_write() : "
+                                               "Server async_read_some() registration again END.");
+                               }
+                               /*------ DEBUG LOG END ------*/
+                       } else {
+                               if (error.value() == boost::asio::error::connection_reset) {
+                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 6, 
+                                               "Reset connection. Normal END : %s.",
+                                               error.message().c_str());
+                               } else if (error.value() == boost::asio::error::broken_pipe) {
+                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 7, 
+                                               "Pipe broken. Normal END : %s.",
+                                               error.message().c_str());
+                               } else {
+                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 20, 
+                                               "Client write NG : %s.",
+                                               error.message().c_str());
+                               }
+                               destroy_session(this);
+                       }
+
+               } catch (...) {
+                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 21, 
+                               "Exception occured in void sslproxy_session::handle_client_write().");
+                       destroy_session(this);
+               }
+
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 41,
+                               "out_function : void sslproxy_session::handle_client_write("
+                               "const boost::system::error_code& error, "
+                               "size_t bytes_transferred)");
+               }
+               /*------ DEBUG LOG END ------*/
+       }
+}
+
+/*!
+ * Edit client message function.
+ * Add, delete or change client message.
+ *
+ * @param[in,out]      bytes_transferred       transferred data size before,after edit
+ */
+void sslproxy_session::edit_client_message(size_t& bytes_transferred)
+{
+    packet_editor editor(this);
+    editor.edit_client(client_buffer, bytes_transferred);
+}
+
+/*!
+ * Edit server message function.
+ * Add, delete or change server message.
+ *
+ * @param[in,out]      bytes_transferred       transferred data size before,after edit
+ */
+void sslproxy_session::edit_server_message(size_t& bytes_transferred)
+{
+    packet_editor editor(this);
+    editor.edit_server(server_buffer, bytes_transferred);
+}