2 * @file sslproxysession.cpp
3 * @brief module of SSLproxy_session
4 * @brief SSL handshaking and Connecting.
5 * @brief Client and Server data read/write.
7 * Copyright (C) 2008 NTT COMWARE Corporation.
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 **********************************************************************
26 * Distributed under the Boost Software Licence, Version 1.0
27 * http://www.boost.org/LICENSE_1_0.txt
29 **********************************************************************/
31 #include <sys/syscall.h> // for SYS_gettid
32 #include <boost/lexical_cast.hpp>
34 #include "sslproxyserver.h"
35 #include "sslproxysession.h"
36 #include "http_message.h"
37 #include "http_request.h"
38 #include "http_response.h"
40 // sslproxy_session constructor
42 * SSLproxy_session constructor.
44 * @param[in] io_service IO event dispatcher
45 * @param[in] context SSL context
46 * @param[in] itr endpoint iterator
48 sslproxy_session::sslproxy_session(boost::asio::io_service& ioservice,
49 boost::asio::ssl::context& context,
50 boost::asio::ip::tcp::resolver::iterator itr)
52 server_socket(ioservice),
53 client_socket(ioservice, context),
54 endpoint_iterator(itr),
56 cancel_time(timeout_sec),
64 cache_timer(ioservice)
66 /*-------- DEBUG LOG --------*/
67 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
68 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 1,
69 "in/out_function : Constructor sslproxy_session::sslproxy_session("
70 "boost::asio::io_service& ioservice, "
71 "boost::asio::ssl::context& context, "
72 "boost::asio::ip::tcp::resolver::iterator itr)");
74 /*------ DEBUG LOG END ------*/
75 pthread_mutex_init(&client_socket_mutex, NULL);
79 * SSLproxy_session destructor.
81 sslproxy_session::~sslproxy_session()
83 /*-------- DEBUG LOG --------*/
84 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
85 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 2,
86 "in/out_function : Destructor sslproxy_session::~sslproxy_session("
89 /*------ DEBUG LOG END ------*/
93 * Low level socket getting function.
95 * @return password string
96 * @retval ssl_socket::lowest_layer_type&
98 ssl_socket::lowest_layer_type& sslproxy_session::low_socket()
100 /*-------- DEBUG LOG --------*/
101 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
102 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 3,
103 "in_function : ssl_socket::lowest_layer_type& sslproxy_session::low_socket("
106 /*------ DEBUG LOG END ------*/
109 ssl_socket::lowest_layer_type& sock = client_socket.lowest_layer();
110 /*-------- DEBUG LOG --------*/
111 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
112 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 4,
113 "function : ssl_socket::lowest_layer_type& sslproxy_session::low_socket() : "
114 "lowest_layer() END.");
116 /*------ DEBUG LOG END ------*/
118 /*-------- DEBUG LOG --------*/
119 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
120 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 5,
121 "out_function : ssl_socket::lowest_layer_type& sslproxy_session::low_socket("
124 /*------ DEBUG LOG END ------*/
126 } catch (std::exception& e) {
127 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 1,
128 "Get low level socket error : %s.", e.what());
134 * Get remote endpoint string.
135 * get client address:port from SSL socket
137 * @param[in] socket client SSL socket
138 * @return endpoint string
140 std::string sslproxy_session::get_remote_endpoint(ssl_socket& socket)
142 /*-------- DEBUG LOG --------*/
143 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
144 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 6,
145 "in_function : std::string sslproxy_session::get_remote_endpoint("
146 "ssl_socket& socket)");
148 /*------ DEBUG LOG END ------*/
150 std::string endpoint_str = "";
151 boost::asio::ip::tcp::endpoint endpoint;
157 endpoint = socket.lowest_layer().remote_endpoint();
158 /*-------- DEBUG LOG --------*/
159 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
160 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 7,
161 "function : std::string sslproxy_session::get_remote_endpoint() : "
162 "lowest_layer().remote_endpoint() END.");
164 /*------ DEBUG LOG END ------*/
165 } catch (std::exception& e) {
166 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 2,
167 "Get remote endpoint from socket error : %s.", e.what());
172 address = endpoint.address().to_string();
173 /*-------- DEBUG LOG --------*/
174 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
175 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 8,
176 "function : std::string sslproxy_session::get_remote_endpoint() : "
177 "address().to_string() END.");
179 /*------ DEBUG LOG END ------*/
180 } catch (std::exception& e) {
181 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 3,
182 "Get address string error : %s.", e.what());
187 port = boost::lexical_cast<std::string>(endpoint.port());
188 /*-------- DEBUG LOG --------*/
189 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
190 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 9,
191 "function : std::string sslproxy_session::get_remote_endpoint() : "
192 "lexical_cast(port()) END.");
194 /*------ DEBUG LOG END ------*/
195 } catch (std::exception& e) {
196 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 4,
197 "Get port string error : %s.", e.what());
201 endpoint_str = address + ":" + port;
202 /*-------- DEBUG LOG --------*/
203 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
204 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 10,
205 "function : std::string sslproxy_session::get_remote_endpoint() : "
206 "Get remote endpoint string END.");
208 /*------ DEBUG LOG END ------*/
211 /*-------- DEBUG LOG --------*/
212 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
213 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 11,
214 "function : std::string sslproxy_session::get_remote_endpoint() : "
215 "get_remote_endpoint() error.");
217 /*------ DEBUG LOG END ------*/
220 /*-------- DEBUG LOG --------*/
221 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
222 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 12,
223 "out_function : std::string sslproxy_session::get_remote_endpoint("
224 "ssl_socket& socket) : "
226 endpoint_str.c_str());
228 /*------ DEBUG LOG END ------*/
233 * Session start function.
234 * Start async handshake and Set handshake timer
236 void sslproxy_session::start()
238 /*-------- DEBUG LOG --------*/
239 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
240 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 13,
241 "in_function : void sslproxy_session::start(void)");
243 /*------ DEBUG LOG END ------*/
245 // Output connection log. (info level)
246 if (conn_log_flag == "on") {
247 LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_CONNECTION, 1,
248 "Connect from [%s] to [%s]. %s",
249 get_remote_endpoint(client_socket).c_str(),
250 target_endpoint.c_str(), target_id.c_str());
254 if(sessionTable.end() != sessionTable.find((long)this)) {
255 // Start async handshake and Set handshake handler.
256 client_socket.async_handshake(boost::asio::ssl::stream_base::server,
257 boost::bind(&sslproxy_session::handle_handshake,
259 boost::asio::placeholders::error));
260 /*-------- DEBUG LOG --------*/
261 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
262 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 14,
263 "function : void sslproxy_session::start() : "
264 "async_handshake() registration END.");
266 /*------ DEBUG LOG END ------*/
268 // Set handshake expire time.
270 timer.expires_from_now(boost::posix_time::seconds(cancel_time));
271 /*-------- DEBUG LOG --------*/
272 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
273 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 15,
274 "function : void sslproxy_session::start() : "
275 "expires_from_now() END. "
279 /*------ DEBUG LOG END ------*/
280 } catch (std::exception& e) {
281 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 5,
282 "Set handshake expire time error : %s.", e.what());
286 // Start timer waiting and Set timer handler.
287 timer.async_wait(boost::bind(&sslproxy_session::cancel,
289 boost::asio::placeholders::error));
290 /*-------- DEBUG LOG --------*/
291 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
292 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 16,
293 "function : void sslproxy_session::start() : "
294 "async_wait() END.");
296 /*------ DEBUG LOG END ------*/
299 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 6,
300 "Exception occured in sslproxy_session::start().");
301 destroy_session(this);
304 /*-------- DEBUG LOG --------*/
305 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
306 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 17,
307 "outfunction : void sslproxy_session::start(void)");
309 /*------ DEBUG LOG END ------*/
313 * Handshake timeout handler function.
315 * @param[in] error error code
317 void sslproxy_session::cancel(const boost::system::error_code& error)
319 // Check session is not already delete.
320 if(sessionTable.end() != sessionTable.find((long)this)) {
321 // Check timout and finishing status.
322 if (istimeout || finishing) {
323 destroy_session(this);
325 /*-------- DEBUG LOG --------*/
326 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
327 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 18,
328 "in_function : void sslproxy_session::cancel("
329 "const boost::system::error_code& error) : "
330 "error = %d, handshaked = %d",
331 error.value(), handshaked);
333 /*------ DEBUG LOG END ------*/
336 // Check session is not already delete.
337 if(sessionTable.end() != sessionTable.find((long)this)) {
340 // When handshake not finished then timer is timeout.
341 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 7,
342 "Handshake timer wait : %d giveup.", cancel_time);
344 client_socket.lowest_layer().cancel();
346 // When handshake finished then timer is diable.
347 /*-------- DEBUG LOG --------*/
348 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
349 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 19,
350 "function : void sslproxy_session::cancel() : "
351 "Handshake timer is cancel.");
353 /*------ DEBUG LOG END ------*/
357 if (error.value() == ECANCELED) {
358 LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 1,
359 "Handshake timer operation cancel. Normal END : %s.",
360 error.message().c_str());
362 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 8,
363 "Handshake timer wait NG : %s.",
364 error.message().c_str());
368 /*-------- DEBUG LOG --------*/
369 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
370 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 20,
371 "out_function : void sslproxy_session::cancel("
372 "const boost::system::error_code& error)");
374 /*------ DEBUG LOG END ------*/
380 * Session cache expire handler function.
382 * @param[in] error error code
384 void sslproxy_session::cache_expire(const boost::system::error_code& error)
386 // Check session is not already delete.
387 if(sessionTable.end() != sessionTable.find((long)this)) {
389 // Server event remain.
390 server_socket.cancel();
392 if (error.value() == ECANCELED) {
393 LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 8,
394 "Cache expire operation cancel. Normal END : %s.",
395 error.message().c_str());
397 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 22,
398 "Cache expire wait NG : %s.",
399 error.message().c_str());
407 * Destroy session function.
409 * @param[in] session session object
411 void sslproxy_session::destroy_session(sslproxy_session* session)
413 /*-------- DEBUG LOG --------*/
414 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
415 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 21,
416 "in_function : void sslproxy_session::destroy_session("
417 "sslproxy_session* session)");
419 /*------ DEBUG LOG END ------*/
421 // Check session is not already delete.
422 if(sessionTable.end() != sessionTable.find((long)session)) {
424 if (!c_r_event && !c_w_event && !s_r_event && !s_w_event) {
426 pthread_mutex_lock(&sessionTable_mutex);
427 sessionTable.erase((long)session);
428 pthread_mutex_unlock(&sessionTable_mutex);
429 pthread_mutex_lock(&client_socket_mutex);
433 if (c_r_event || c_w_event) {
434 // Client event remain.
436 client_socket.lowest_layer().cancel();
438 } else if (s_r_event || s_w_event) {
439 // Server event remain.
440 // Set expire time for session cache.
441 cache_timer.expires_from_now(boost::posix_time::seconds(session_cache_timeout));
442 cache_timer.async_wait(boost::bind(&sslproxy_session::cache_expire,
444 boost::asio::placeholders::error));
451 * Hnadshake handling function.
452 * Check hendshake result and Start async connect.
454 * @param[in] error error code
456 void sslproxy_session::handle_handshake(const boost::system::error_code& error)
458 // Check timout and finishing status.
459 if (istimeout || finishing) {
460 destroy_session(this);
462 /*-------- DEBUG LOG --------*/
463 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
464 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 22,
465 "in_function : void sslproxy_session::handle_handshake("
466 "const boost::system::error_code& error) : "
467 "error = %d, istimeout = %d",
468 error.value(), istimeout);
470 /*------ DEBUG LOG END ------*/
473 // Check handshake result.
475 // Connect to server after handshake
476 boost::asio::ip::tcp::resolver::iterator end;
477 if (endpoint_iterator != end) {
478 // Start async connect
479 server_socket.async_connect(*endpoint_iterator++,
480 boost::bind(&sslproxy_session::handle_connect,
482 boost::asio::placeholders::error));
483 /*-------- DEBUG LOG --------*/
484 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
485 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 23,
486 "function : void sslproxy_session::handle_handshake() : "
487 "async_connect() registration END.");
489 /*------ DEBUG LOG END ------*/
491 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 9,
492 "Server endpoint is nothing for connect.");
493 destroy_session(this);
496 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 10,
497 "Handshaking NG : %s.",
498 error.message().c_str());
499 destroy_session(this);
503 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 11,
504 "Exception occured in sslproxy_session::handle_handshake().");
505 destroy_session(this);
508 /*-------- DEBUG LOG --------*/
509 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
510 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 24,
511 "out_function : void sslproxy_session::handle_handshake("
512 "const boost::system::error_code& error)");
514 /*------ DEBUG LOG END ------*/
519 * Connect handling function.
520 * Check connect result and Start async read client.
522 * @param[in] error error code
524 void sslproxy_session::handle_connect(const boost::system::error_code& error)
526 // Check timout and finishing status.
527 if (istimeout || finishing) {
528 destroy_session(this);
530 /*-------- DEBUG LOG --------*/
531 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
532 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 25,
533 "in_function : void sslproxy_session::handle_connect("
534 "const boost::system::error_code& error) : "
535 "error = %d, istimeout = %d",
536 error.value(), istimeout);
538 /*------ DEBUG LOG END ------*/
541 // Check connect result.
545 // Start async read client.
547 pthread_mutex_lock(&client_socket_mutex);
548 client_socket.async_read_some(boost::asio::buffer(client_buffer, MAX_READ_SIZE),
549 boost::bind(&sslproxy_session::handle_client_read,
551 boost::asio::placeholders::error,
552 boost::asio::placeholders::bytes_transferred));
553 pthread_mutex_unlock(&client_socket_mutex);
554 /*-------- DEBUG LOG --------*/
555 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
556 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 26,
557 "function : void sslproxy_session::handle_connect() : "
558 "Client async_read_some() registration END.");
560 /*------ DEBUG LOG END ------*/
562 // Start async read server.
564 server_socket.async_read_some(boost::asio::buffer(server_buffer, MAX_READ_SIZE),
565 boost::bind(&sslproxy_session::handle_server_read,
567 boost::asio::placeholders::error,
568 boost::asio::placeholders::bytes_transferred));
569 /*-------- DEBUG LOG --------*/
570 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
571 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 27,
572 "function : void sslproxy_session::handle_connect() : "
573 "Server async_read_some() registration END.");
575 /*------ DEBUG LOG END ------*/
577 boost::asio::ip::tcp::resolver::iterator end;
578 if (endpoint_iterator != end) {
579 // Retry connect to server
580 LOGGER_PUT_LOG_WARN(LOG_CAT_SSLPROXY_SESSION, 1,
581 "Connecting NG : %s. Retry connect.",
582 error.message().c_str());
583 server_socket.async_connect(*endpoint_iterator++,
584 boost::bind(&sslproxy_session::handle_connect,
586 boost::asio::placeholders::error));
587 /*-------- DEBUG LOG --------*/
588 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
589 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 28,
590 "function : void sslproxy_session::handle_connect() : "
591 "async_connect() retry registration END.");
593 /*------ DEBUG LOG END ------*/
595 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 12,
596 "Connecting NG : %s.",
597 error.message().c_str());
598 destroy_session(this);
602 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 13,
603 "Exception occured in void sslproxy_session::handle_connect().");
604 destroy_session(this);
607 /*-------- DEBUG LOG --------*/
608 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
609 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 29,
610 "out_function : void sslproxy_session::handle_connect("
611 "const boost::system::error_code& error)");
613 /*------ DEBUG LOG END ------*/
618 * Client read handling function.
619 * Check client read result and Start async write server.
621 * @param[in] error error code
622 * @param[in] bytes_transferred transferred data size
624 void sslproxy_session::handle_client_read(const boost::system::error_code& error,
625 size_t bytes_transferred)
628 // Check timout and finishing status.
629 if (istimeout || finishing) {
630 destroy_session(this);
632 /*-------- DEBUG LOG --------*/
633 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
634 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 30,
635 "in_function : void sslproxy_session::handle_client_read("
636 "const boost::system::error_code& error, "
637 "size_t bytes_transferred) : "
638 "error = %d, bytes_transferred = %d, istimeout = %d",
639 error.value(), (int)bytes_transferred, istimeout);
641 /*------ DEBUG LOG END ------*/
644 // Check client read result.
646 // Edit client message if necessary.
648 edit_client_message(bytes_transferred);
649 // Start async write server.
651 boost::asio::async_write(server_socket,
652 boost::asio::buffer(client_buffer, bytes_transferred),
653 boost::bind(&sslproxy_session::handle_server_write,
655 boost::asio::placeholders::error,
657 /*-------- DEBUG LOG --------*/
658 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
659 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 31,
660 "function : void sslproxy_session::handle_client_read() : "
661 "Server async_write() registration END.");
663 /*------ DEBUG LOG END ------*/
665 if (error.value() == boost::asio::error::eof) {
666 // When End of file. Client data read complete.
667 LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 2,
668 "Client data read complete. Normal END : %s.",
669 error.message().c_str());
670 } else if (error.value() == boost::asio::error::shut_down) {
671 LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 3,
672 "Client already shutdown. Normal END : %s.",
673 error.message().c_str());
674 } else if (error.value() == boost::asio::error::operation_aborted) {
675 LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 4,
676 "Client read operation canceled. Normal END : %s.",
677 error.message().c_str());
679 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 14,
680 "Client read NG : %s.",
681 error.message().c_str());
683 destroy_session(this);
687 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 15,
688 "Exception occured in void sslproxy_session::handle_client_read().");
689 destroy_session(this);
692 /*-------- DEBUG LOG --------*/
693 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
694 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 32,
695 "out_function : void sslproxy_session::handle_client_read("
696 "const boost::system::error_code& error, "
697 "size_t bytes_transferred)");
699 /*------ DEBUG LOG END ------*/
704 * Server write handling function.
705 * Check server write result and Start async read server.
707 * @param[in] error error code
708 * @param[in] bytes_transferred transferred data size
710 void sslproxy_session::handle_server_write(const boost::system::error_code& error,
711 size_t bytes_transferred)
714 // Check timout and finishing status.
715 if (istimeout || finishing) {
716 destroy_session(this);
718 /*-------- DEBUG LOG --------*/
719 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
720 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 33,
721 "in_function : void sslproxy_session::handle_server_write("
722 "const boost::system::error_code& error, "
723 "size_t bytes_transferred) : "
724 "error = %d, bytes_transferred = %d, istimeout = %d",
725 error.value(), (int)bytes_transferred, istimeout);
727 /*------ DEBUG LOG END ------*/
730 // Check server write result.
732 // Next client data wait, start async read client again.
734 pthread_mutex_lock(&client_socket_mutex);
735 client_socket.async_read_some(boost::asio::buffer(client_buffer, MAX_READ_SIZE),
736 boost::bind(&sslproxy_session::handle_client_read,
738 boost::asio::placeholders::error,
739 boost::asio::placeholders::bytes_transferred));
740 pthread_mutex_unlock(&client_socket_mutex);
741 /*-------- DEBUG LOG --------*/
742 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
743 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 34,
744 "function : void sslproxy_session::handle_server_write() : "
745 "Client async_read_some() registration again END.");
747 /*------ DEBUG LOG END ------*/
749 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 16,
750 "Server write NG : %s.",
751 error.message().c_str());
752 destroy_session(this);
756 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 17,
757 "Exception occured in void sslproxy_session::handle_server_write().");
758 destroy_session(this);
761 /*-------- DEBUG LOG --------*/
762 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
763 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 35,
764 "out_function : void sslproxy_session::handle_server_write("
765 "const boost::system::error_code& error, "
766 "size_t bytes_transferred)");
768 /*------ DEBUG LOG END ------*/
773 * Server read handling function.
774 * Check server read result and Start async write client.
776 * @param[in] error error code
777 * @param[in] bytes_transferred transferred data size
779 void sslproxy_session::handle_server_read(const boost::system::error_code& error,
780 size_t bytes_transferred)
783 // Check timout and finishing status.
784 if (istimeout || finishing) {
785 destroy_session(this);
787 /*-------- DEBUG LOG --------*/
788 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
789 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 36,
790 "in_function : void sslproxy_session::handle_server_read("
791 "const boost::system::error_code& error, "
792 "size_t bytes_transferred) : "
793 "error = %d, bytes_transferred = %d, istimeout = %d",
794 error.value(), (int)bytes_transferred, istimeout);
796 /*------ DEBUG LOG END ------*/
799 // Check server read result.
801 // Start async write client.
803 pthread_mutex_lock(&client_socket_mutex);
804 boost::asio::async_write(client_socket,
805 boost::asio::buffer(server_buffer, bytes_transferred),
806 boost::bind(&sslproxy_session::handle_client_write,
808 boost::asio::placeholders::error,
810 pthread_mutex_unlock(&client_socket_mutex);
811 /*-------- DEBUG LOG --------*/
812 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
813 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 37,
814 "function : void sslproxy_session::handle_server_read() : "
815 "Client async_write() registration END.");
817 /*------ DEBUG LOG END ------*/
819 if (error.value() == boost::asio::error::eof) {
820 // When End of file. Server data read complete.
821 LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 5,
822 "Server data read complete. Normal END : %s.",
823 error.message().c_str());
825 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 18,
826 "Server read NG : %s.",
827 error.message().c_str());
829 destroy_session(this);
833 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 19,
834 "Exception occured in void sslproxy_session::handle_server_read().");
835 destroy_session(this);
838 /*-------- DEBUG LOG --------*/
839 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
840 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 38,
841 "out_function : void sslproxy_session::handle_server_read("
842 "const boost::system::error_code& error, "
843 "size_t bytes_transferred)");
845 /*------ DEBUG LOG END ------*/
850 * Client write handling function.
851 * Check client write result and Start async read client.
853 * @param[in] error error code
854 * @param[in] bytes_transferred transferred data size
856 void sslproxy_session::handle_client_write(const boost::system::error_code& error,
857 size_t bytes_transferred)
860 // Check timout and finishing status.
861 if (istimeout || finishing) {
862 destroy_session(this);
864 /*-------- DEBUG LOG --------*/
865 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
866 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 39,
867 "in_function : void sslproxy_session::handle_client_write("
868 "const boost::system::error_code& error, "
869 "size_t bytes_transferred) : "
870 "error = %d, bytes_transferred = %d, istimeout = %d",
871 error.value(), (int)bytes_transferred, istimeout);
873 /*------ DEBUG LOG END ------*/
876 // Check client write result.
878 // Next server data wait, start async read server again.
880 server_socket.async_read_some(boost::asio::buffer(server_buffer, MAX_READ_SIZE),
881 boost::bind(&sslproxy_session::handle_server_read,
883 boost::asio::placeholders::error,
884 boost::asio::placeholders::bytes_transferred));
885 /*-------- DEBUG LOG --------*/
886 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
887 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 40,
888 "function : void sslproxy_session::handle_client_write() : "
889 "Server async_read_some() registration again END.");
891 /*------ DEBUG LOG END ------*/
893 if (error.value() == boost::asio::error::connection_reset) {
894 LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 6,
895 "Reset connection. Normal END : %s.",
896 error.message().c_str());
897 } else if (error.value() == boost::asio::error::broken_pipe) {
898 LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 7,
899 "Pipe broken. Normal END : %s.",
900 error.message().c_str());
902 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 20,
903 "Client write NG : %s.",
904 error.message().c_str());
906 destroy_session(this);
910 LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 21,
911 "Exception occured in void sslproxy_session::handle_client_write().");
912 destroy_session(this);
915 /*-------- DEBUG LOG --------*/
916 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
917 LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 41,
918 "out_function : void sslproxy_session::handle_client_write("
919 "const boost::system::error_code& error, "
920 "size_t bytes_transferred)");
922 /*------ DEBUG LOG END ------*/
927 * Edit client message function.
928 * Add, delete or change client message.
930 * @param[in,out] bytes_transferred transferred data size before,after edit
932 void sslproxy_session::edit_client_message(size_t& bytes_transferred)
934 if (x_forwarded_for_mode != NONE_X_FORWARDED_FOR ||
935 custom_field != "") {
938 // Parse HTTP request
939 http_request request(std::string(client_buffer, bytes_transferred));
941 field_map_iterator begin, end;
944 // Edit X_FORWARDED_FOR header field.
945 switch (x_forwarded_for_mode) {
946 case NONE_X_FORWARDED_FOR:
948 case ADD_X_FORWARDED_FOR:
949 headers = request.header("X-Forwarded-For");
950 begin = headers.first;
951 end = headers.second;
953 while (begin != end) {
954 // Already exist header
955 request.header("X-Forwarded-For", begin->second + ", " + get_remote_endpoint(client_socket));
960 request.header("X-Forwarded-For", get_remote_endpoint(client_socket));
963 case SET_X_FORWARDED_FOR:
964 request.header("X-Forwarded-For", get_remote_endpoint(client_socket));
966 case DELETE_X_FORWARDED_FOR:
967 request.header("X-Forwarded-For", "");
971 // Edit X_FORWARDED_FOR header field.
972 if (custom_field != "") {
975 std::string new_client_buffer = request.as_string();
976 if (new_client_buffer.length() <= MAX_BUFFER_SIZE) {
977 memcpy(client_buffer, new_client_buffer.c_str(), new_client_buffer.length());
978 bytes_transferred = new_client_buffer.length();
982 // XXX http request parse error