2 * @file tcp_ssl_socket.cpp
3 * @brief tcp ssl session socket class
5 * L7VSD: Linux Virtual Server for Layer7 Load Balancing
6 * Copyright (C) 2009 NTT COMWARE Corporation.
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 **********************************************************************/
25 #include <boost/thread/thread.hpp>
27 #include "tcp_ssl_socket.h"
33 //! @param[in] handshake_type is handshaking as a server or client
34 //! @return true is handshake success
35 //! @return false is handshake failure
36 bool tcp_ssl_socket::handshake(boost::system::error_code &ec)
38 if (unlikely(LOG_LV_DEBUG == Logger::getLogLevel(
39 LOG_CAT_L7VSD_SESSION))) {
40 Logger::putLogDebug(LOG_CAT_L7VSD_SESSION, 74,
41 "in_function : tcp_ssl_socket::handshake",
45 rw_scoped_lock scope_lock(close_mutex);
48 my_socket->handshake(boost::asio::ssl::stream_base::server, ec);
51 } else if (ec != boost::asio::error::try_again) {
52 handshake_error_flag = true;
55 if (unlikely(LOG_LV_DEBUG == Logger::getLogLevel(
56 LOG_CAT_L7VSD_SESSION))) {
57 Logger::putLogDebug(LOG_CAT_L7VSD_SESSION, 78,
58 "out_function : tcp_ssl_socket::handshake",
65 void tcp_ssl_socket::accept()
67 rw_scoped_lock scope_lock(close_mutex);
70 //----Debug log--------------------------------------------------------
71 if (unlikely(LOG_LV_DEBUG == Logger::getLogLevel(
72 LOG_CAT_L7VSD_SESSION))) {
73 boost::system::error_code ec;
74 std::stringstream buf;
76 buf << boost::this_thread::get_id();
77 buf << "] tcp_ssl_socket::accept [";
78 buf << my_socket->lowest_layer().remote_endpoint(ec);
80 Logger::putLogDebug(LOG_CAT_L7VSD_SESSION, 54, buf.str(),
83 //----Debug log--------------------------------------------------------
86 if (opt_info.nodelay_opt) {
87 boost::system::error_code ec;
88 boost::asio::ip::tcp::no_delay set_option(opt_info.nodelay_val);
89 my_socket->lowest_layer().set_option(set_option, ec);
92 Logger::putLogError(LOG_CAT_L7VSD_SESSION, 107,
93 "socket option(TCP_NODELAY) set failed" ,
99 if (opt_info.cork_opt) {
100 boost::system::error_code ec;
101 int val = opt_info.cork_val;
102 size_t len = sizeof(val);
103 int err = ::setsockopt(my_socket->lowest_layer().native(), IPPROTO_TCP,
104 TCP_CORK, &val, len);
107 Logger::putLogError(LOG_CAT_L7VSD_SESSION, 108,
108 "socket option(TCP_CORK) set failed" ,
115 //! @param[out] ec is reference error code object
116 //! @return true is socket close
117 //! @return false is not open socket
118 bool tcp_ssl_socket::close(boost::system::error_code &ec)
120 if (unlikely(LOG_LV_DEBUG == Logger::getLogLevel(
121 LOG_CAT_L7VSD_SESSION))) {
122 Logger::putLogDebug(LOG_CAT_L7VSD_SESSION, 56,
123 "in_function : tcp_ssl_socket::close", __FILE__, __LINE__);
126 rw_scoped_lock scope_lock(close_mutex);
128 //----Debug log--------------------------------------------------------
129 if (unlikely(LOG_LV_DEBUG == Logger::getLogLevel(
130 LOG_CAT_L7VSD_SESSION))) {
132 boost::system::error_code ec;
133 std::stringstream buf;
135 buf << boost::this_thread::get_id();
136 buf << "] tcp_ssl_socket::close [";
137 buf << my_socket->lowest_layer().remote_endpoint(ec);
139 Logger::putLogDebug(LOG_CAT_L7VSD_SESSION, 58, buf.str(),
143 //----Debug log--------------------------------------------------------
145 if (likely(open_flag)) {
149 my_socket->shutdown(ec);
150 my_socket->lowest_layer().close(ec);
152 if (unlikely(LOG_LV_DEBUG == Logger::getLogLevel(
153 LOG_CAT_L7VSD_SESSION))) {
154 Logger::putLogDebug(LOG_CAT_L7VSD_SESSION, 57,
155 "out_function : tcp_ssl_socket::close", __FILE__, __LINE__);
160 //! set non blocking mode of the socket
161 //! @param[out] ec is reference error code object
162 //! @return true is set non blocking mode
163 //! @return false is set non blocking mode failure
164 bool tcp_ssl_socket::set_non_blocking_mode(boost::system::error_code &ec)
166 if (unlikely(LOG_LV_DEBUG == Logger::getLogLevel(
167 LOG_CAT_L7VSD_SESSION))) {
168 Logger::putLogDebug(LOG_CAT_L7VSD_SESSION, 60,
169 "in_function : tcp_ssl_socket::set_non_blocking_mode",
173 rd_scoped_lock scope_lock(close_mutex);
175 boost::asio::socket_base::non_blocking_io cmd(true);
176 my_socket->lowest_layer().io_control(cmd, ec);
180 non_blocking_flag = true;
183 if (unlikely(LOG_LV_DEBUG == Logger::getLogLevel(
184 LOG_CAT_L7VSD_SESSION))) {
185 Logger::putLogDebug(LOG_CAT_L7VSD_SESSION, 61,
186 "out_function : tcp_ssl_socket::set_non_blocking_mode",
193 //! @param[in] buffers is write data buffer
194 //! @param[out] ec is reference error code object
195 //! @return write data size
196 std::size_t tcp_ssl_socket::write_some(
197 boost::asio::mutable_buffers_1 buffers,
198 boost::system::error_code &ec)
200 if (unlikely(LOG_LV_DEBUG == Logger::getLogLevel(
201 LOG_CAT_L7VSD_SESSION))) {
202 Logger::putLogDebug(LOG_CAT_L7VSD_SESSION, 63,
203 "in_function : tcp_ssl_socket::write_some",
207 rw_scoped_lock scope_lock(close_mutex);
208 std::size_t res_size = 0;
209 if (likely(non_blocking_flag)) {
210 res_size = my_socket->write_some(buffers, ec);
212 if (likely(!open_flag)) {
218 if (unlikely(LOG_LV_DEBUG == Logger::getLogLevel(
219 LOG_CAT_L7VSD_SESSION))) {
220 Logger::putLogDebug(LOG_CAT_L7VSD_SESSION, 64,
221 "out_function : tcp_ssl_socket::write_some",
228 //! @param[out] buffers is read data buffer
229 //! @param[out] ec is reference error code object
230 //! @return read data size
231 std::size_t tcp_ssl_socket::read_some(
232 boost::asio::mutable_buffers_1 buffers,
233 boost::system::error_code &ec)
236 rw_scoped_lock scope_lock(close_mutex);
237 std::size_t res_size = 0;
238 if (unlikely(open_flag && non_blocking_flag)) {
240 if (opt_info.quickack_opt) {
241 int val = opt_info.quickack_val;
242 std::size_t len = sizeof(val);
243 int err = ::setsockopt(my_socket->lowest_layer().native(), IPPROTO_TCP,
244 TCP_QUICKACK, &val, len);
247 std::stringstream buf;
249 buf << boost::this_thread::get_id();
250 buf << "] socket option(TCP_QUICKACK) set failed : ";
252 Logger::putLogError(LOG_CAT_L7VSD_SESSION, 109,
253 buf.str() , __FILE__, __LINE__);
256 boost::this_thread::yield();
257 res_size = my_socket->read_some(buffers, ec);