OSDN Git Service

fix for_gcc4.7 degrade #30300 patch.
[ultramonkey-l7/ultramonkey-l7-v3.git] / l7vsd / module / protocol / protocol_module_ip.cpp
1 /*
2  * @file  protocol_module_ip.cpp
3  * @brief protocol module of any protocol.
4  * @brief this module never keep session persistence.
5  *
6  * L7VSD: Linux Virtual Server for Layer7 Load Balancing
7  * Copyright (C) 2009  NTT COMWARE Corporation.
8  *
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.
13  *
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.
18  *
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
22  * 02110-1301 USA
23  *
24  **********************************************************************/
25
26 #include <vector>
27 #include <list>
28 #include <algorithm>
29 #include <iostream>
30 #include <boost/asio/ip/tcp.hpp>
31 #include <boost/format.hpp>
32 #include <boost/xpressive/xpressive.hpp>
33 #include "protocol_module_ip.h"
34 #include "http_utility.h"
35 #include "utility.h"
36
37 namespace l7vs
38 {
39
40 const std::string protocol_module_ip::MODULE_NAME = "ip";
41 const int protocol_module_ip::THREAD_DIVISION_UP_STREAM = 0;
42 const int protocol_module_ip::THREAD_DIVISION_DOWN_STREAM = 1;
43
44 const int protocol_module_ip::END_FLAG_OFF = 0;
45 const int protocol_module_ip::END_FLAG_ON = 1;
46
47 const int protocol_module_ip::ACCEPT_END_FLAG_OFF = 0;
48 const int protocol_module_ip::ACCEPT_END_FLAG_ON = 1;
49
50 const int protocol_module_ip::SORRY_FLAG_ON = 1;
51 const int protocol_module_ip::SORRY_FLAG_OFF = 0;
52
53 const int protocol_module_ip::SWITCH_FLAG_OFF = 0;
54 const int protocol_module_ip::SWITCH_FLAG_ON = 1;
55
56 const int protocol_module_ip::FORWARDED_FOR_OFF = 0;
57 const int protocol_module_ip::FORWARDED_FOR_ON = 1;
58
59 const int protocol_module_ip::COLLECT_STATS_OFF = 0;
60 const int protocol_module_ip::COLLECT_STATS_ON = 1;
61
62 using namespace boost::xpressive;
63 //! constructor
64 protocol_module_ip::protocol_module_ip() :
65         ip_protocol_module_base(MODULE_NAME), forwarded_for(FORWARDED_FOR_OFF)
66 {
67         sorry_uri.assign('\0');
68         sorry_uri[0] = '/';
69 }
70 //! destructor
71 protocol_module_ip::~protocol_module_ip()
72 {
73 }
74 //! tcp protocol support check
75 //! @return tcp support is true
76 //! @return tcp not-support is false
77 bool protocol_module_ip::is_tcp()
78 {
79         /*-------- DEBUG LOG --------*/
80         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
81                 putLogDebug(600000, "in/out_function : bool protocol_module_ip::is_tcp() : return_value = true.",
82                             __FILE__, __LINE__);
83         }
84         /*------DEBUG LOG END------*/
85         return true;
86 }
87
88 //! udp protocol support check
89 //! @return udp support is true
90 //! @return udp not-support is false
91 bool protocol_module_ip::is_udp()
92 {
93         /*-------- DEBUG LOG --------*/
94         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
95                 putLogDebug(600001, "in/out_function : bool protocol_module_ip::is_udp() : return_value = false.",
96                             __FILE__, __LINE__);
97         }
98         /*------DEBUG LOG END------*/
99         return false;
100 }
101
102 //! replication interval interrupt
103 //! timer thread call this function. from virtualservice.
104 void protocol_module_ip::replication_interrupt()
105 {
106         /*-------- DEBUG LOG --------*/
107         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
108                 putLogDebug(600002, "in_function : protocol_module_ip::replication_interrupt().", __FILE__, __LINE__);
109         }
110         /*------DEBUG LOG END------*/
111         if (replication_data_processor) {
112                 replication_data_processor->write_replication_area();
113                 /*-------- DEBUG LOG --------*/
114                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
115                         putLogDebug(600003, "function : protocol_module_ip::replication_interrupt() : "
116                                     "write_replication_area() end.", __FILE__, __LINE__);
117                 }
118                 /*------DEBUG LOG END------*/
119         }
120         /*-------- DEBUG LOG --------*/
121         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
122                 putLogDebug(600004, "out_function : void protocol_module_ip::replication_interrupt().", __FILE__, __LINE__);
123         }
124         /*------DEBUG LOG END------*/
125 }
126 //! initialize function. called from module control. module loaded call
127 //! @param[in]    realserver list iterator begin function object type
128 //!    @param[in]    realserver list iterator end function object type
129 //! @param[in]    realserver list iterator next function object type
130 //! @param[in]    realserver list mutex lock function object type.
131 //! @param[in]    realserver list mutex unlock function object type
132 void protocol_module_ip::initialize(rs_list_itr_func_type    inlist_begin,
133                                     rs_list_itr_func_type    inlist_end,
134                                     rs_list_itr_next_func_type    inlist_next,
135                                     boost::function< void(void) >    inlist_lock,
136                                     boost::function< void(void) >    inlist_unlock)
137 {
138         /*-------- DEBUG LOG --------*/
139         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
140                 putLogDebug(600005, "in_function : void protocol_module_ip::initialize("
141                             "rs_list_itr_func_type inlist_begin, rs_list_itr_func_type inlist_end, "
142                             "rs_list_itr_next_func_type inlist_next, boost::function< void(void) > "
143                             "inlist_lock, boost::function< void(void) > inlist_unlock).", __FILE__, __LINE__);
144         }
145         /*------DEBUG LOG END------*/
146
147         //RealServer list begin function
148         rs_list_begin = inlist_begin;
149         //RealServer list end function
150         rs_list_end = inlist_end;
151         //RealServer list next function
152         rs_list_next = inlist_next;
153         //RealServer list lock function
154         rs_list_lock = inlist_lock;
155         //RealServer list unlock function
156         rs_list_unlock = inlist_unlock;
157
158         /*-------- DEBUG LOG --------*/
159         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
160                 putLogDebug(600006, "out_function : void protocol_module_ip::initialize("
161                             "rs_list_itr_func_type inlist_begin, rs_list_itr_func_type inlist_end, "
162                             "rs_list_itr_next_func_type inlist_next, boost::function< void(void) > "
163                             "inlist_lock, boost::function< void(void) > inlist_unlock).", __FILE__, __LINE__);
164         }
165         /*------DEBUG LOG END------*/
166 }
167
168 //! finalize called from module control. module unloaded call.
169 void protocol_module_ip::finalize()
170 {
171         /*-------- DEBUG LOG --------*/
172         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
173                 putLogDebug(600007, "in_function : void protocol_module_ip::finalize().", __FILE__, __LINE__);
174         }
175         /*------DEBUG LOG END------*/
176
177         //RealServer list functions initialization
178         //RealServer list begin function
179         rs_list_begin.clear();
180         //RealServer list end function
181         rs_list_end.clear();
182         //RealServer list next function
183         rs_list_next.clear();
184         //RealServer list lock function
185         rs_list_lock.clear();
186         //RealServer list unlock function
187         rs_list_unlock.clear();
188
189         //Replication functions initialization
190         //component memory allocate function
191         replication_pay_memory.clear();
192         //component memory lock function
193         replication_area_lock.clear();
194         //component memory unlock function
195         replication_area_unlock.clear();
196
197         /*-------- DEBUG LOG --------*/
198         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
199                 putLogDebug(600008, "function : void protocol_module_ip::finalize() : "
200                             "rs_list_begin.clear(), rs_list_end.clear(), rs_list_next.clear(), "
201                             "rs_list_lock.clear(), rs_list_unlock.clear() end.", __FILE__, __LINE__);
202         }
203         /*------DEBUG LOG END------*/
204
205         //ScheduleModule's functions initialization
206         schedule_tcp.clear();
207
208         /*-------- DEBUG LOG --------*/
209         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
210                 putLogDebug(600009, "function : void protocol_module_ip::finalize() : "
211                             "schedule_tcp.clear() end.", __FILE__, __LINE__);
212         }
213         /*------DEBUG LOG END------*/
214
215         //Module's option initialization
216         //forwarded_for
217         forwarded_for = FORWARDED_FOR_OFF;
218         //sorry-uri
219         sorry_uri.assign('\0');
220         //time_out
221         timeout = 0;
222         //reschedule flag
223         reschedule = 0;
224
225         // replication initialize
226         if (replication_data_processor) {
227                 /*-------- DEBUG LOG --------*/
228                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
229                         boost::format formatter("delete : address = &(%d).");
230                         formatter % static_cast<void *>(replication_data_processor);
231                         putLogDebug(600010, formatter.str(), __FILE__, __LINE__);
232                 }
233                 /*------DEBUG LOG END------*/
234
235                 delete replication_data_processor;
236                 replication_data_processor = NULL;
237         }
238
239         // session initialize
240         if (ip_data_processor) {
241                 /*-------- DEBUG LOG --------*/
242                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
243                         boost::format formatter("delete : address = &(%d).");
244                         formatter % static_cast<void *>(ip_data_processor);
245                         putLogDebug(600011, formatter.str(), __FILE__, __LINE__);
246                 }
247                 /*------DEBUG LOG END------*/
248
249                 delete ip_data_processor;
250                 ip_data_processor = NULL;
251         }
252
253         /*-------- DEBUG LOG --------*/
254         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
255                 putLogDebug(600012, "out_function : void protocol_module_ip::finalize().", __FILE__, __LINE__);
256         }
257         /*------DEBUG LOG END------*/
258
259         //logger functions initialization
260         //log level getting function
261         getloglevel.clear();
262         //logger(Fatal)
263         putLogFatal.clear();
264         //logger(Error)
265         putLogError.clear();
266         //logger(Warn)
267         putLogWarn.clear();
268         //logger(Info)
269         putLogInfo.clear();
270         //logger(Debug)
271         putLogDebug.clear();
272 }
273
274 //! sorry support check
275 //! @return true sorry mode is supported.
276 //! @return false sorry mode is unsupported.
277 bool protocol_module_ip::is_use_sorry()
278 {
279         /*-------- DEBUG LOG --------*/
280         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
281                 putLogDebug(600013, "in/out_function : bool protocol_module_ip::is_use_sorry() : return_value = true.",
282                             __FILE__, __LINE__);
283         }
284         /*------DEBUG LOG END------*/
285         return true;
286 }
287
288 //! realserver list update event
289 void protocol_module_ip::handle_rslist_update()
290 {
291         /*-------- DEBUG LOG --------*/
292         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
293                 putLogDebug(600014, "in/out_function : void protocol_module_ip::handle_rslist_update().",
294                             __FILE__, __LINE__);
295         }
296         /*------DEBUG LOG END------*/
297 }
298
299 //! module parameter check.used by l7vsadm
300 //! @param[in]    module parameter string list
301 //! @return    result.flag true is parameter is no problem.
302 //! @return result.flag false is parameter is problem.
303 protocol_module_base::check_message_result protocol_module_ip::check_parameter(const std::vector <
304                 std::string > & args)
305 {
306         /*-------- DEBUG LOG --------*/
307         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
308                 boost::format formatter("in_function : protocol_module_ip::check_message_result "
309                                         "protocol_module_ip::check_parameter("
310                                         "const std::vector<std::string>& args) : args = %s.");
311                 std::string argsdump;
312                 for (std::vector<std::string>::const_iterator it = args.begin(); it != args.end(); ++it) {
313                         argsdump += *it;
314                 }
315                 formatter % argsdump;
316                 putLogDebug(600015, formatter.str(), __FILE__, __LINE__);
317         }
318         /*------DEBUG LOG END------*/
319
320         //set check result true
321         // set check result flag true
322         check_message_result check_result;
323         check_result.flag = true;
324         bool timeout_flag = false;
325         bool reschedule_flag = false;
326         bool no_reschedule_flag = false;
327         bool sorryuri_checked = false;
328         bool stats_checked = false;
329
330         // cf RFC 2396 (A. Collected BNF for URI)
331         sregex    sorry_uri_regex
332         =    +('/' >>
333                *(
334                        alpha | digit |
335                        (set = '-', '_', '.', '!', '~', '*', '\'', '(', ')') |
336                        '%' >> repeat<2>(xdigit) |
337                        (set = ':', '@', '&', '=', '+', '$', ',')
338                )
339                >>
340                *(';' >>
341                  *(
342                          alpha | digit |
343                          (set = '-', '_', '.', '!', '~', '*', '\'', '(', ')') | // mark
344                          '%' >> repeat<2>(xdigit) | // escaped
345                          (set = ':', '@', '&', '=', '+', '$', ',')
346                  ) // pchar
347                 ) // param
348               ) // segment
349              >>
350              !('?' >>
351                *(
352                        (set = ';', '/', '?', ':', '@', '&', '=', '+', '$', ',') | //reserved
353                        alpha | digit |
354                        (set = '-', '_', '.', '!', '~', '*', '\'', '(', ')') | // mark
355                        '%' >> repeat<2>(xdigit) // escaped
356                ) // uric
357               ) // query
358              >>
359              !('#' >>
360                *(
361                        (set = ';', '/', '?', ':', '@', '&', '=', '+', '$', ',') | //reserved
362                        alpha | digit |
363                        (set = '-', '_', '.', '!', '~', '*', '\'', '(', ')') | // mark
364                        '%' >> repeat<2>(xdigit) // escaped
365                ) // uric
366               ); // fragment
367
368         typedef std::vector<std::string>::const_iterator vec_str_it;
369
370         try {
371                 vec_str_it it = args.begin();
372                 vec_str_it it_end = args.end();
373                 boost::format formatter;
374
375                 //loop option strings
376                 for (; it != it_end;) {
377                         if (*it == "-T" || *it == "--timeout") {
378                                 // timeout
379                                 if (!timeout_flag) {
380                                         // not set timeout option
381                                         ++it;
382                                         // next parameter exist check
383                                         if (it != it_end) {
384                                                 // next parameter exist
385                                                 if ((*it).substr(0, 1) == "-" || (*it).substr(0, 2) == "--") {
386                                                         continue;
387                                                 }
388
389                                                 try {
390                                                         unsigned long ultimeout = 0;
391                                                         ultimeout = boost::lexical_cast<unsigned long>(*it);
392                                                         // int max value check
393                                                         if (ultimeout > INT_MAX) {
394                                                                 check_result.flag = false;
395                                                                 formatter.parse("'-T/--timeout' option value '%s' is too large.");
396                                                                 formatter % *it;
397                                                                 check_result.message = formatter.str();
398                                                                 putLogError(600000, check_result.message, __FILE__, __LINE__);
399                                                                 break;
400                                                         } else {
401                                                                 timeout_flag = true;
402                                                                 ++it;
403                                                                 continue;
404                                                         }
405                                                 } catch (boost::bad_lexical_cast &e) {
406                                                         // not numeric character
407                                                         check_result.flag = false;
408                                                         formatter.parse("'-T/--timeout' option value '%s' is not numeric character.");
409                                                         formatter % *it;
410                                                         check_result.message = formatter.str();
411                                                         putLogError(600001, check_result.message, __FILE__, __LINE__);
412                                                         break;
413                                                 }
414                                         } else {
415                                                 break;
416                                         }
417                                 } else {
418                                         // already set timeout
419                                         check_result.flag = false;
420                                         check_result.message = "Cannot set multiple option '-T/--timeout'.";
421                                         putLogError(600002, check_result.message, __FILE__, __LINE__);
422                                         break;
423                                 }
424                         } else if (*it == "-R" || *it == "--reschedule") {
425                                 // reschedule
426                                 if (!no_reschedule_flag) {
427                                         // not set no-reschedule flag
428                                         reschedule_flag = true;
429                                 } else {
430                                         // already set no-reschedule flag
431                                         check_result.flag = false;
432                                         check_result.message = "You have to choose either of reschedule or no-reschedule.";
433                                         putLogError(600003, check_result.message, __FILE__, __LINE__);
434                                         break;
435                                 }
436                         } else if (*it == "-N" || *it == "--no-reschedule") {
437                                 // no-reschedule
438                                 if (!reschedule_flag) {
439                                         // not set reschedule flag
440                                         no_reschedule_flag = true;
441                                 } else {
442                                         // already set reschedule flag
443                                         check_result.flag = false;
444                                         check_result.message = "You have to choose either of reschedule or no-reschedule.";
445                                         putLogError(600004, check_result.message, __FILE__, __LINE__);
446                                         break;
447                                 }
448                         }
449                         //option string = "-F"
450                         else if (*it == "-F" || *it == "--forwarded-for") {
451                                 //set forward flag ON
452                                 ++it;
453                                 continue;
454                         }
455                         //option string = "-S"
456                         else if (*it == "-S" || *it == "--sorry-uri") {
457                                 //set sorryURI flag OFF
458                                 if (!sorryuri_checked) {
459                                         //next item exist
460                                         if (++it != it_end) {
461                                                 if (!it->empty() && (it->substr(0, 1) == "-" || it->substr(0, 2) == "--")) {
462                                                         //set check result flag false
463                                                         check_result.flag = false;
464                                                         //set check result message
465                                                         check_result.message = "You have to set option value '-S/--sorry-uri'.";
466                                                         putLogError(600005, check_result.message, __FILE__, __LINE__);
467                                                         //loop break;
468                                                         break;
469                                                 }
470                                                 //next option string's length > 127
471                                                 if (it->size() > MAX_OPTION_SIZE - 1) {
472                                                         std::ostringstream ostr;
473                                                         ostr << "'-S/--sorry-uri' option value '" << *it << "' is too long.";
474
475                                                         //set check result flag false
476                                                         check_result.flag = false;
477                                                         //set check result message
478                                                         check_result.message = ostr.str();
479                                                         putLogError(600006, check_result.message, __FILE__, __LINE__);
480                                                         //loop break;
481                                                         break;
482                                                 }
483                                                 //next option string's length <= 127
484                                                 else {
485                                                         //regex check
486                                                         if (regex_match(*it, sorry_uri_regex)) {
487                                                                 //check OK
488                                                                 //set sorryURI flag ON
489                                                                 sorryuri_checked = true;
490                                                         }
491                                                         //check NG
492                                                         else {
493                                                                 std::ostringstream ostr;
494                                                                 ostr << "'-S/--sorry-uri' option value '" << *it << "' is not a valid URI.";
495
496                                                                 //set check result flag false
497                                                                 check_result.flag = false;
498                                                                 //set check result message
499                                                                 check_result.message = ostr.str();
500                                                                 putLogError(600007, check_result.message, __FILE__, __LINE__);
501                                                                 break;
502                                                         }
503                                                 }
504                                         }
505                                         //next item is not exist
506                                         else {
507                                                 //set check flag false
508                                                 check_result.flag = false;
509                                                 //set check result message
510                                                 check_result.message = "You have to set option value '-S/--sorry-uri'.";
511                                                 putLogError(600008, check_result.message, __FILE__,
512                                                             __LINE__);
513                                                 //loop break
514                                                 break;
515                                         }
516                                 }
517                                 //sorryURI flag = ON
518                                 else {
519                                         //set check result flag false
520                                         check_result.flag = false;
521                                         //set check result message
522                                         check_result.message = "Cannot set multiple option '-S/--sorry-uri'.";
523                                         putLogError(600009, check_result.message, __FILE__,
524                                                     __LINE__);
525                                         //loop break
526                                         break;
527                                 }
528                         }
529                         //option string = "-c/--statistic"
530                         else if (*it == "-c" || *it == "--statistic") {
531                                 //statistic flag is OFF
532                                 if (!stats_checked) {
533                                         //next item exist
534                                         if (++it != it_end) {
535                                                 //collect statistic flag must be 0 or 1
536                                                 if (*it == "0" || *it == "1") {
537                                                         //check OK
538                                                         //set statistic flag ON
539                                                         stats_checked = true;
540                                                 } else {
541                                                         std::ostringstream ostr;
542                                                         ostr << "'-c/--statistic' option value '" << *it << "' is not a valid value.";
543
544                                                         //set check result flag false
545                                                         check_result.flag = false;
546                                                         //set check result message
547                                                         check_result.message = ostr.str();
548                                                         putLogError(600114, check_result.message, __FILE__, __LINE__);
549                                                         //loop break
550                                                         break;
551                                                 }
552                                         }
553                                         //next item is not exist
554                                         else {
555                                                 //set check flag false
556                                                 check_result.flag = false;
557                                                 //set check result message
558                                                 check_result.message = "You have to set option value '-c/--statistic'.";
559                                                 putLogError(600115, check_result.message, __FILE__, __LINE__);
560                                                 //loop break
561                                                 break;
562                                         }
563                                 }
564                                 //statistic flag is ON
565                                 else {
566                                         //set check result flag false
567                                         check_result.flag = false;
568                                         //set check result message
569                                         check_result.message = "Cannot set multiple option '-c/--statistic'.";
570                                         putLogError(600116, check_result.message, __FILE__, __LINE__);
571                                         //loop break
572                                         break;
573                                 }
574                         }
575                         //other option string
576                         else {
577                                 //set check result flag false
578                                 check_result.flag = false;
579                                 //set check result message
580                                 check_result.message = "Option error.";
581                                 putLogError(600010, check_result.message, __FILE__, __LINE__);
582                                 //loop break
583                                 break;
584                         }
585
586                         ++it;
587                 }
588         } catch (const std::exception &ex) {
589                 check_result.flag = false;
590                 std::cerr << "protocol_module_ip::check_parameter() : exception : error = " << ex.what() << "." << std::endl;
591                 boost::format formatter("function : protocol_module_base::check_message_result "
592                                         "protocol_module_ip::check_parameter() exception : "
593                                         "error = %s.");
594                 formatter % ex.what();
595                 putLogError(600011, formatter.str(), __FILE__, __LINE__);
596         } catch (...) {
597                 check_result.flag = false;
598                 std::cerr << "protocol_module_ip::check_parameter() : Unknown exception." << std::endl;
599                 putLogError(600012, "function : protocol_module_base::check_message_result "
600                             "protocol_module_ip::check_parameter() : "
601                             "Unknown exception.", __FILE__, __LINE__);
602         }
603
604         /*-------- DEBUG LOG --------*/
605         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
606                 boost::format formatter("out_function : protocol_module_base::check_message_result "
607                                         "protocol_module_ip::check_parameter("
608                                         "const std::vector<std::string>& args) : return_value = ("
609                                         "check_message_result.flag = %d, check_message_result.message = %s).");
610                 formatter % check_result.flag % check_result.message;
611                 putLogDebug(600016, formatter.str(), __FILE__, __LINE__);
612         }
613         /*------DEBUG LOG END------*/
614
615         return check_result;
616 }
617
618 //! parameter set
619 //! @param[in] module parameter string list
620 //! @return    result.flag true is parameter is no problem.
621 //! @return result.flag false is parameter is problem.
622 protocol_module_base::check_message_result protocol_module_ip::set_parameter(const std::vector <
623                 std::string > & args)
624 {
625         /*-------- DEBUG LOG --------*/
626         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
627                 boost::format formatter("in_function : protocol_module_base::check_message_result "
628                                         "protocol_module_ip::set_parameter("
629                                         "const std::vector<std::string>& args) : args = %s.");
630                 std::string argsdump;
631                 for (std::vector<std::string>::const_iterator it = args.begin(); it != args.end(); ++it) {
632                         argsdump += *it;
633                         argsdump += " ";
634                 }
635                 formatter % argsdump;
636                 putLogDebug(600017, formatter.str(), __FILE__, __LINE__);
637         }
638         /*------DEBUG LOG END------*/
639
640         //set check result flag true
641         check_message_result check_result;
642         check_result.flag = true;
643         bool timeout_flag = false;
644         bool reschedule_flag = false;
645         bool no_reschedule_flag = false;
646         bool forward_checked = false;
647         bool sorryuri_checked = false;
648         bool stats_checked = false;
649         boost::format formatter;
650
651         // cf RFC 2396 (A. Collected BNF for URI)
652         sregex    sorry_uri_regex
653         =    +('/' >>
654                *(
655                        alpha | digit |
656                        (set = '-', '_', '.', '!', '~', '*', '\'', '(', ')') |
657                        '%' >> repeat<2>(xdigit) |
658                        (set = ':', '@', '&', '=', '+', '$', ',')
659                )
660                >>
661                *(';' >>
662                  *(
663                          alpha | digit |
664                          (set = '-', '_', '.', '!', '~', '*', '\'', '(', ')') | // mark
665                          '%' >> repeat<2>(xdigit) | // escaped
666                          (set = ':', '@', '&', '=', '+', '$', ',')
667                  ) // pchar
668                 ) // param
669               ) // segment
670              >>
671              !('?' >>
672                *(
673                        (set = ';', '/', '?', ':', '@', '&', '=', '+', '$', ',') | //reserved
674                        alpha | digit |
675                        (set = '-', '_', '.', '!', '~', '*', '\'', '(', ')') | // mark
676                        '%' >> repeat<2>(xdigit) // escaped
677                ) // uric
678               ) // query
679              >>
680              !('#' >>
681                *(
682                        (set = ';', '/', '?', ':', '@', '&', '=', '+', '$', ',') | //reserved
683                        alpha | digit |
684                        (set = '-', '_', '.', '!', '~', '*', '\'', '(', ')') | // mark
685                        '%' >> repeat<2>(xdigit) // escaped
686                ) // uric
687               ); // fragment
688
689         typedef std::vector<std::string>::const_iterator vec_str_it;
690
691         //set forwarded flag true
692         forwarded_for = 1;
693
694         try {
695                 vec_str_it it = args.begin();
696                 vec_str_it it_end = args.end();
697
698                 for (; it != it_end;) {
699
700                         if (*it == "-T" || *it == "--timeout") {
701                                 // timeout
702                                 if (!timeout_flag) {
703                                         // not set timeout option
704                                         ++it;
705                                         // next parameter exist check
706                                         if (it != it_end) {
707                                                 // next parameter exist
708                                                 if ((*it).substr(0, 1) == "-" || (*it).substr(0, 2) == "--") {
709                                                         continue;
710                                                 }
711
712                                                 try {
713                                                         unsigned long ultimeout = 0;
714                                                         ultimeout = boost::lexical_cast<unsigned long>(*it);
715                                                         // int max value check
716                                                         if (ultimeout > INT_MAX) {
717                                                                 check_result.flag = false;
718                                                                 formatter.parse("'-T/--timeout' option value '%s' is too large.");
719                                                                 formatter % *it;
720                                                                 check_result.message = formatter.str();
721                                                                 putLogError(600013, check_result.message, __FILE__, __LINE__);
722                                                                 break;
723                                                         } else {
724                                                                 timeout_flag = true;
725                                                                 timeout = ultimeout;
726                                                                 ++it;
727                                                                 continue;
728                                                         }
729                                                 } catch (boost::bad_lexical_cast &e) {
730                                                         // not numeric character
731                                                         check_result.flag = false;
732                                                         formatter.parse("'-T/--timeout' option value '%s' is not numeric character.");
733                                                         formatter % *it;
734                                                         check_result.message = formatter.str();
735                                                         putLogError(600014, check_result.message, __FILE__, __LINE__);
736                                                         break;
737                                                 }
738                                         } else {
739                                                 break;
740                                         }
741                                 } else {
742                                         // already set timeout
743                                         check_result.flag = false;
744                                         check_result.message = "Cannot set multiple option '-T/--timeout'.";
745                                         putLogError(600015, check_result.message, __FILE__, __LINE__);
746                                         break;
747
748                                 }
749                         } else if (*it == "-R" || *it == "--reschedule") {
750                                 // reschedule
751                                 if (!no_reschedule_flag) {
752                                         // not set no-reschedule flag
753                                         reschedule_flag = true;
754                                         reschedule = 1;
755                                 } else {
756                                         // already set no-reschedule flag
757                                         check_result.flag = false;
758                                         check_result.message = "You have to choose either of reschedule or no-reschedule.";
759                                         putLogError(600016, check_result.message, __FILE__, __LINE__);
760                                         break;
761                                 }
762                         } else if (*it == "-N" || *it == "--no-reschedule") {
763                                 // no-reschedule
764                                 if (!reschedule_flag) {
765                                         // not set reschedule flag
766                                         no_reschedule_flag = true;
767                                         reschedule = 0;
768
769                                 } else {
770                                         // already set reschedule flag
771                                         check_result.flag = false;
772                                         check_result.message = "You have to choose either of reschedule or no-reschedule.";
773                                         putLogError(600017, check_result.message, __FILE__, __LINE__);
774                                         break;
775                                 }
776                         }
777                         //option string = "-F"
778                         else if (*it == "-F" || *it == "--forwarded-for") {
779                                 //set forwarded flag ON
780                                 forward_checked = true;
781                                 forwarded_for = FORWARDED_FOR_ON;
782                         }
783                         //option string  = "-S"
784                         else if (*it == "-S" || *it == "--sorry-uri") {
785                                 //sorryURI flag = OFF
786                                 if (!sorryuri_checked) {
787                                         //next item exist
788                                         if (++it != it_end) {
789                                                 if (!it->empty() && (it->substr(0, 1) == "-" || it->substr(0, 2) == "--")) {
790                                                         //set check result flag false
791                                                         check_result.flag = false;
792                                                         //set check result message
793                                                         check_result.message = "You have to set option value '-S/--sorry-uri'.";
794                                                         //loop break
795                                                         break;
796                                                 }
797                                                 //next option string's length > 127
798                                                 if (it->size() > MAX_OPTION_SIZE - 1) {
799                                                         std::ostringstream ostr;
800                                                         ostr << "'-S/--sorry-uri' option value '" << *it << "' is too long.";
801
802                                                         //set check result flag false
803                                                         check_result.flag = false;
804                                                         //set check result message
805                                                         check_result.message = ostr.str();
806                                                         putLogError(600018, check_result.message, __FILE__,
807                                                                     __LINE__);
808                                                         //loop break
809                                                         break;
810                                                 }
811                                                 //next option string's length <= 127
812                                                 else {
813                                                         //regex check
814                                                         //check OK
815                                                         if (regex_match(*it, sorry_uri_regex)) {
816                                                                 sorryuri_checked = true;
817                                                                 memcpy(sorry_uri.data(), it->c_str(), it->size());
818                                                         }
819                                                         //check NG
820                                                         else {
821                                                                 std::ostringstream ostr;
822                                                                 ostr << "'-S/--sorry-uri' option value '" << *it << "' is not a valid URI.";
823
824                                                                 //set check result flag false
825                                                                 check_result.flag = false;
826                                                                 //set check result message
827                                                                 check_result.message = ostr.str();
828                                                                 putLogError(600019, check_result.message, __FILE__,
829                                                                             __LINE__);
830                                                                 break;
831                                                         }
832                                                 }
833                                         }
834                                         //next item not exist
835                                         else {
836                                                 //set check result flag false
837                                                 check_result.flag = false;
838                                                 //set check result message
839                                                 check_result.message = "You have to set option value '-S/--sorry-uri'.";
840                                                 putLogError(600020, check_result.message, __FILE__,
841                                                             __LINE__);
842                                                 break;
843                                         }
844                                 }
845
846                                 //sorryURI flag = ON
847                                 else {
848                                         //set check result flag false
849                                         check_result.flag = false;
850                                         //set check result message
851                                         check_result.message = "Cannot set multiple option '-S/--sorry-uri'.";
852                                         putLogError(600021, check_result.message, __FILE__, __LINE__);
853                                         break;
854                                 }
855                         }
856
857                         //option string = "-c/--statistic"
858                         else if (*it == "-c" || *it == "--statistic") {
859                                 //statistic flag is OFF
860                                 if (!stats_checked) {
861                                         //next item exist
862                                         if (++it != it_end) {
863                                                 //collect statistic flag must be 0 or 1
864                                                 if (*it == "0" || *it == "1") {
865                                                         //check OK
866                                                         //set statistic flag ON
867                                                         stats_checked = true;
868
869                                                         //set collect statistic flag
870                                                         statistic = boost::lexical_cast<int>(*it);
871                                                 } else {
872                                                         std::ostringstream ostr;
873                                                         ostr << "'-c/--statistic' option value '" << *it << "' is not a valid value.";
874
875                                                         //set check result flag false
876                                                         check_result.flag = false;
877                                                         //set check result message
878                                                         check_result.message = ostr.str();
879                                                         putLogError(600117, check_result.message, __FILE__, __LINE__);
880                                                         //loop break
881                                                         break;
882                                                 }
883                                         }
884                                         //next item is not exist
885                                         else {
886                                                 //set check flag false
887                                                 check_result.flag = false;
888                                                 //set check result message
889                                                 check_result.message = "You have to set option value '-c/--statistic'.";
890                                                 putLogError(600118, check_result.message, __FILE__, __LINE__);
891                                                 //loop break
892                                                 break;
893                                         }
894                                 }
895                                 //statistic flag is ON
896                                 else {
897                                         //set check result flag false
898                                         check_result.flag = false;
899                                         //set check result message
900                                         check_result.message = "Cannot set multiple option '-c/--statistic'.";
901                                         putLogError(600119, check_result.message, __FILE__, __LINE__);
902                                         //loop break
903                                         break;
904                                 }
905                         }
906                         //others
907                         else {
908                                 //set check result flag false
909                                 check_result.flag = false;
910                                 //set check result message
911                                 check_result.message = "Option error.";
912                                 putLogError(600022, check_result.message, __FILE__, __LINE__);
913
914                                 break;
915                         }
916                         ++it;
917                 }
918
919                 // result check
920                 if (check_result.flag) {
921                         // set timeout default value
922                         if (!timeout_flag) {
923                                 timeout = 3600;
924                         }
925
926                         // set reschedule default value
927                         if (!reschedule_flag) {
928                                 reschedule = 0;
929                         }
930                         //forward flag = OFF
931                         if (!forward_checked) {
932                                 forwarded_for = 0;
933                         }
934                         //collect statistic flag = OFF
935                         if (!stats_checked) {
936                                 statistic = COLLECT_STATS_OFF;
937                         }
938                 }
939                 /*-------- DEBUG LOG --------*/
940                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
941                         boost::format formatter("function : protocol_module_ip::check_message_result "
942                                                 "protocol_module_ip::set_parameter(const std::vector<std::string>& args) : "
943                                                 "timeout = %d, reschedule = %d.");
944                         formatter % timeout  % reschedule;
945                         putLogDebug(600018, formatter.str(), __FILE__, __LINE__);
946                 }
947                 /*------DEBUG LOG END------*/
948
949                 unsigned int data_size = 0;
950                 void *data_addr = NULL;
951                 data_addr = replication_pay_memory(get_name(), &data_size);
952
953                 /*-------- DEBUG LOG --------*/
954                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
955                         putLogDebug(600019, "function : protocol_module_ip::check_message_result protocol_module_ip::"
956                                     "set_parameter() : replication_pay_memory() end.", __FILE__, __LINE__);
957                         boost::format formatter("function : protocol_module_ip::check_message_result protocol_module_ip::"
958                                                 "set_parameter() : data_addr = &(%d), data_size = %d.");
959                         formatter % data_addr % data_size;
960                         putLogDebug(600020, formatter.str(), __FILE__, __LINE__);
961                 }
962
963                 /*------DEBUG LOG END------*/
964                 if (data_addr == NULL || data_size <= 0) {
965                         // replication area is null
966                         putLogInfo(600000, "Replication area is null.", __FILE__, __LINE__);
967
968                         /*-------- DEBUG LOG --------*/
969                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
970                                 putLogDebug(600021, "function : protocol_module_ip::check_message_result "
971                                             "protocol_module_ip::set_parameter() : "
972                                             "Replication area is null.", __FILE__, __LINE__);
973                         }
974                         /*------DEBUG LOG END------*/
975                 }
976
977                 // create ip_replication_data_processor
978                 replication_data_processor = new ip_replication_data_processor(
979                         static_cast<char *>(data_addr),
980                         data_size,
981                         virtual_service_endpoint_tcp,
982                         getloglevel,
983                         putLogFatal,
984                         putLogError,
985                         putLogWarn,
986                         putLogInfo,
987                         putLogDebug);
988
989                 /*-------- DEBUG LOG --------*/
990                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
991                         boost::format formatter("new : address = &(%d), size = %lu.");
992                         formatter % static_cast<void *>(replication_data_processor)
993                         % sizeof(ip_replication_data_processor);
994                         putLogDebug(600022, formatter.str(), __FILE__, __LINE__);
995                 }
996                 /*------DEBUG LOG END------*/
997
998                 replication_data_processor->register_replication_area_lock(replication_area_lock);
999
1000                 /*-------- DEBUG LOG --------*/
1001                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1002                         putLogDebug(600023, "function : protocol_module_ip::check_message_result protocol_module_ip::"
1003                                     "set_parameter() : register_replication_area_lock() end.", __FILE__, __LINE__);
1004                 }
1005                 /*------DEBUG LOG END------*/
1006
1007                 replication_data_processor->register_replication_area_unlock(replication_area_unlock);
1008
1009                 /*-------- DEBUG LOG --------*/
1010                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1011                         putLogDebug(600024, "function : protocol_module_ip::check_message_result protocol_module_ip::"
1012                                     "set_parameter() : register_replication_area_unlock() end.", __FILE__, __LINE__);
1013                 }
1014                 /*------DEBUG LOG END------*/
1015
1016                 // create ip_session_data_processor
1017                 ip_data_processor = new ip_session_data_processor(
1018                         timeout,
1019                         replication_data_processor,
1020                         getloglevel,
1021                         putLogFatal,
1022                         putLogError,
1023                         putLogWarn,
1024                         putLogInfo,
1025                         putLogDebug);
1026
1027                 /*-------- DEBUG LOG --------*/
1028                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1029                         boost::format formatter("new : address = &(%d), size = %lu.");
1030                         formatter % static_cast<void *>(ip_data_processor)
1031                         % sizeof(ip_session_data_processor);
1032                         putLogDebug(600025, formatter.str(), __FILE__, __LINE__);
1033                 }
1034                 /*------DEBUG LOG END------*/
1035
1036                 // restore data from replication area
1037                 ip_replication_data *redata = replication_data_processor->get_replication_area();
1038
1039                 /*-------- DEBUG LOG --------*/
1040                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1041                         putLogDebug(600026, "function : protocol_module_ip::check_message_result protocol_module_ip::"
1042                                     "set_parameter() : get_replication_area() end.", __FILE__, __LINE__);
1043                 }
1044                 /*------DEBUG LOG END------*/
1045
1046                 if (data_addr) {
1047                         replication_area_lock();
1048
1049                         /*-------- DEBUG LOG --------*/
1050                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1051                                 putLogDebug(600027, "function : protocol_module_ip::check_message_result protocol_module_ip::"
1052                                             "set_parameter() : replication_area_lock() end.", __FILE__, __LINE__);
1053                         }
1054                         /*------DEBUG LOG END------*/
1055
1056                         ip_data_processor->read_session_data_from_replication_area(redata);
1057
1058                         /*-------- DEBUG LOG --------*/
1059                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1060                                 putLogDebug(600028, "function : protocol_module_ip::check_message_result protocol_module_ip::"
1061                                             "set_parameter() : read_session_data_from_replication_area() end.", __FILE__, __LINE__);
1062                         }
1063                         /*------DEBUG LOG END------*/
1064
1065                         replication_area_unlock();
1066
1067                         /*-------- DEBUG LOG --------*/
1068                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1069                                 putLogDebug(600029, "function : protocol_module_ip::check_message_result protocol_module_ip::"
1070                                             "set_parameter() : replication_area_unlock() end.", __FILE__, __LINE__);
1071                         }
1072                         /*------DEBUG LOG END------*/
1073                 }
1074         } catch (const std::bad_alloc &ba) {
1075                 if (replication_data_processor) {
1076                         delete replication_data_processor;
1077                         replication_data_processor = NULL;
1078                 }
1079
1080                 if (ip_data_processor) {
1081                         delete ip_data_processor;
1082                         ip_data_processor = NULL;
1083                 }
1084
1085                 std::cerr << "protocol_module_ip::set_parameter() : exception : Could not allocate memory." << std::endl;
1086                 check_result.flag = false;
1087                 check_result.message = "Could not allocate memory.";
1088                 putLogError(600023, check_result.message, __FILE__, __LINE__);
1089         } catch (const std::exception &ex) {
1090                 if (replication_data_processor) {
1091                         delete replication_data_processor;
1092                         replication_data_processor = NULL;
1093                 }
1094
1095                 if (ip_data_processor) {
1096                         delete ip_data_processor;
1097                         ip_data_processor = NULL;
1098                 }
1099
1100                 check_result.flag = false;
1101                 std::cerr << "protocol_module_ip::set_parameter() : exception : error = " << ex.what() << std::endl;
1102                 boost::format formatter("function : protocol_module_ip::check_message_result "
1103                                         "protocol_module_ip::set_parameter() : exception : error = %s.");
1104                 formatter % ex.what();
1105                 putLogError(600024, formatter.str(), __FILE__, __LINE__);
1106         } catch (...) {
1107                 if (replication_data_processor) {
1108                         delete replication_data_processor;
1109                         replication_data_processor = NULL;
1110                 }
1111
1112                 if (ip_data_processor) {
1113                         delete ip_data_processor;
1114                         ip_data_processor = NULL;
1115                 }
1116
1117                 check_result.flag = false;
1118                 std::cerr << "protocol_module_ip::set_parameter() : Unknown exception." << std::endl;
1119                 putLogError(600025, "function : protocol_module_ip::check_message_result protocol_module_ip::"
1120                             "set_parameter() : Unknown exception.", __FILE__, __LINE__);
1121         }
1122         /*-------- DEBUG LOG --------*/
1123         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1124                 boost::format formatter("out_function : protocol_module_ip::check_message_result "
1125                                         "protocol_module_ip::set_parameter("
1126                                         "const std::vector<std::string>& args) : return_value = ("
1127                                         "check_message_result.flag = %d, check_message_result.message = %s).");
1128                 formatter % check_result.flag % check_result.message;
1129                 putLogDebug(600030, formatter.str(), __FILE__, __LINE__);
1130         }
1131         /*------DEBUG LOG END------*/
1132         return check_result;
1133 }
1134
1135 //! parameter add
1136 //! @param[in] module parameter string list
1137 //! @return    result.flag true is parameter is no problem.
1138 //! @return result.flag false is parameter is problem.
1139 protocol_module_base::check_message_result protocol_module_ip::add_parameter(const std::vector <
1140                 std::string > & args)
1141 {
1142         /*-------- DEBUG LOG --------*/
1143         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1144                 boost::format formatter("in_function : protocol_module_ip::check_message_result protocol_module_ip::"
1145                                         "add_parameter(const std::vector<std::string>& args) : args = %s.");
1146                 std::string argsdump;
1147                 for (std::vector<std::string>::const_iterator it = args.begin(); it != args.end(); ++it) {
1148                         argsdump += *it;
1149                 }
1150                 formatter % argsdump;
1151                 putLogDebug(600031, formatter.str(), __FILE__, __LINE__);
1152         }
1153         /*------DEBUG LOG END------*/
1154         check_message_result check_result;
1155         //set check result flag true
1156         check_result.flag = true;
1157
1158         //param list is not empty
1159         if (!args.empty()) {
1160                 //set check result flag false
1161                 check_result.flag = false;
1162                 //set check result message
1163                 check_result.message = "Cannot add option.";
1164                 putLogError(600026, check_result.message, __FILE__, __LINE__);
1165         }
1166
1167         /*-------- DEBUG LOG --------*/
1168         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1169                 boost::format formatter("out_function : protocol_module_ip::check_message_result "
1170                                         "protocol_module_ip::add_parameter(const std::vector<std::string>& args) : "
1171                                         "return_value = (check_message_result.flag = %d, check_message_result.message = %s).");
1172                 formatter % check_result.flag % check_result.message;
1173                 putLogDebug(600032, formatter.str(), __FILE__, __LINE__);
1174         }
1175         /*------DEBUG LOG END------*/
1176         return check_result;
1177 }
1178
1179 //! get option info
1180 //! @param[out] module parameter string
1181 void protocol_module_ip::get_option_info(std::string &option)
1182 {
1183         /*-------- DEBUG LOG --------*/
1184         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1185                 putLogDebug(600033, "in_function : void protocol_module_ip::get_option_info("
1186                             "std::string& option).", __FILE__, __LINE__);
1187         }
1188         /*------DEBUG LOG END------*/
1189
1190         boost::format option_formatter("--timeout %d%s %s --sorry-uri '%s' --statistic %d");
1191         option_formatter % timeout % (forwarded_for ? " --forwarded-for" : "") % (reschedule ? "--reschedule" : "--no-reschedule")
1192         % sorry_uri.c_array() % statistic;
1193         option.assign(option_formatter.str());
1194
1195         /*-------- DEBUG LOG --------*/
1196         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1197                 boost::format formatter("out_function : void protocol_module_ip::get_option_info("
1198                                         "std::string& option) : option = %s.");
1199                 formatter % option;
1200                 putLogDebug(600034, formatter.str(), __FILE__, __LINE__);
1201         }
1202         /*------DEBUG LOG END------*/
1203 }
1204
1205 //! TCP/IP scheduled function registration.
1206 //! @param[in] schedule module TCP/IP scheduled function object type
1207 void protocol_module_ip::register_schedule(tcp_schedule_func_type inschedule)
1208 {
1209         /*-------- DEBUG LOG --------*/
1210         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1211                 putLogDebug(600035, "in_function : void protocol_module_ip::register_schedule("
1212                             "tcp_schedule_func_type inschedule).", __FILE__, __LINE__);
1213         }
1214         /*------DEBUG LOG END------*/
1215         schedule_tcp = inschedule;
1216         /*-------- DEBUG LOG --------*/
1217         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1218                 putLogDebug(600036, "out_function : void protocol_module_ip::register_schedule("
1219                             "tcp_schedule_func_type inschedule).", __FILE__, __LINE__);
1220         }
1221         /*------DEBUG LOG END------*/
1222 }
1223
1224 //! UDP scheduled function registration
1225 //! @param[in] schedule module UDP scheduled function object type
1226 void protocol_module_ip::register_schedule(udp_schedule_func_type inschedule)
1227 {
1228         /*-------- DEBUG LOG --------*/
1229         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1230                 putLogDebug(600037, "in/out_function : void protocol_module_ip::register_schedule("
1231                             "udp_schedule_func_type inschedule).", __FILE__, __LINE__);
1232         }
1233         /*------DEBUG LOG END------*/
1234 }
1235
1236 //! called from session initialize use in upstream_thread
1237 //! @param[in]    upstream thread id.
1238 //! @param[in]    downstream thread id
1239 //! @return        session use EVENT mode.
1240 protocol_module_base::EVENT_TAG protocol_module_ip::handle_session_initialize(
1241         const boost::thread::id up_thread_id, const boost::thread::id down_thread_id,
1242         const boost::asio::ip::tcp::endpoint &client_endpoint_tcp,
1243         const boost::asio::ip::udp::endpoint &client_endpoint_udp)
1244 {
1245         /*-------- DEBUG LOG --------*/
1246         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1247                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1248                                         "handle_session_initialize(const boost::thread::id up_thread_id, "
1249                                         "const boost::thread::id down_thread_id, "
1250                                         "const boost::asio::ip::tcp::endpoint& client_endpoint_tcp, "
1251                                         "const boost::asio::ip::udp::endpoint& client_endpoint_udp) : "
1252                                         "up_thread_id = %d, down_thread_id = %d.");
1253                 formatter % up_thread_id % down_thread_id;
1254                 putLogDebug(600038, formatter.str(), __FILE__, __LINE__);
1255         }
1256         /*------DEBUG LOG END------*/
1257
1258         EVENT_TAG status = FINALIZE;
1259         unsigned int ip_hash = 0;
1260
1261         //session thread initialization
1262         try {
1263                 thread_data_ptr p_up(new session_thread_data_ip);
1264                 /*-------- DEBUG LOG --------*/
1265                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1266                         boost::format formatter("new : address = &(%d), size = %lu.");
1267                         formatter % static_cast<void *>(p_up.get()) % sizeof(session_thread_data_ip);
1268                         putLogDebug(600039, formatter.str(), __FILE__, __LINE__);
1269                 }
1270                 /*------DEBUG LOG END------*/
1271
1272                 //calculate ip address's hash
1273                 ip_hash = l7vs_ip_service_calc_hash(client_endpoint_tcp);
1274
1275                 p_up->thread_id                = up_thread_id;
1276                 p_up->thread_division            = THREAD_DIVISION_UP_STREAM;
1277                 p_up->pair_thread_id            = down_thread_id;
1278                 p_up->accept_end_flag            = ACCEPT_END_FLAG_OFF;
1279                 p_up->end_flag                = END_FLAG_OFF;
1280                 p_up->sorry_flag                = SORRY_FLAG_OFF;
1281                 p_up->switch_flag                = SWITCH_FLAG_OFF;
1282                 p_up->last_status                = INITIALIZE;
1283                 p_up->client_endpoint            = client_endpoint_tcp;
1284                 p_up->data_buffer                = new char[MAX_BUFFER_SIZE];
1285                 p_up->data_buffer_size            = MAX_BUFFER_SIZE;
1286                 p_up->data_length                = 0;
1287                 p_up->data_offset                = 0;
1288                 p_up->current_message_rest_size        = 0;
1289                 p_up->data_state                = HTTP_START;
1290                 p_up->ip_hash                = ip_hash;
1291
1292                 /*-------- DEBUG LOG --------*/
1293                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1294                         // data dump
1295                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1296                                                 "handle_session_initialize() : session_thread_data_ip(upthread) : "
1297                                                 "thread_id = %d, thread_division = %d, "
1298                                                 "pair_thread_id = %d, accept_end_flag = %d, end_flag = %d, "
1299                                                 "sorry_flag = %d, switch_flag = %d, last_status = %d, client_endpoint = [%s]:%d, data_buffer = &(%d), "
1300                                                 "data_buffer_size = %d, data_length = %d, data_offset = %d, current_message_rest_size = %d, data_state = %d, "
1301                                                 "ip_hash = %d.");
1302                         formatter % p_up->thread_id
1303                         % p_up->thread_division
1304                         % p_up->pair_thread_id
1305                         % p_up->accept_end_flag
1306                         % p_up->end_flag
1307                         % p_up->sorry_flag
1308                         % p_up->switch_flag
1309                         % p_up->last_status
1310                         % p_up->client_endpoint.address().to_string()
1311                         % p_up->client_endpoint.port()
1312                         % p_up->data_buffer
1313                         % p_up->data_buffer_size
1314                         % p_up->data_length
1315                         % p_up->data_offset
1316                         % p_up->current_message_rest_size
1317                         % p_up->data_state
1318                         % p_up->ip_hash;
1319
1320
1321                         putLogDebug(600040, formatter.str(), __FILE__, __LINE__);
1322                 }
1323                 /*------DEBUG LOG END------*/
1324
1325                 thread_data_ptr p_down(new session_thread_data_ip);
1326
1327                 /*-------- DEBUG LOG --------*/
1328                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1329                         boost::format formatter("new : address = &(%d), size = %lu.");
1330                         formatter % static_cast<void *>(p_down.get()) % sizeof(session_thread_data_ip);
1331                         putLogDebug(600041, formatter.str(), __FILE__, __LINE__);
1332                 }
1333                 /*------DEBUG LOG END------*/
1334
1335                 p_down->thread_id                = down_thread_id;
1336                 p_down->thread_division            = THREAD_DIVISION_DOWN_STREAM;
1337                 p_down->pair_thread_id            = up_thread_id;
1338                 p_down->accept_end_flag            = ACCEPT_END_FLAG_OFF;
1339                 p_down->end_flag                = END_FLAG_OFF;
1340                 p_down->sorry_flag                = SORRY_FLAG_OFF;
1341                 p_down->switch_flag                = SWITCH_FLAG_OFF;
1342                 p_down->last_status                = INITIALIZE;
1343                 p_down->client_endpoint            = client_endpoint_tcp;
1344                 p_down->data_buffer                = new char[MAX_BUFFER_SIZE];
1345                 p_down->data_buffer_size            = MAX_BUFFER_SIZE;
1346                 p_down->data_length                = 0;
1347                 p_down->data_offset                = 0;
1348                 p_down->current_message_rest_size        = 0;
1349                 p_down->data_state                = HTTP_START;
1350                 p_down->ip_hash                = ip_hash;
1351
1352                 /*-------- DEBUG LOG --------*/
1353                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1354                         // data_dump
1355                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1356                                                 "handle_session_initialize() : session_thread_data_ip(downthread) : "
1357                                                 "thread_id = %d, thread_division = %d, "
1358                                                 "pair_thread_id = %d, accept_end_flag = %d, end_flag = %d, "
1359                                                 "sorry_flag = %d, switch_flag = %d, last_status = %d, client_endpoint = [%s]:%d, data_buffer = &(%d), "
1360                                                 "data_buffer_size = %d, data_length = %d, data_offset = %d, current_message_rest_size = %d, data_state = %d, "
1361                                                 "ip_hash = %d.");
1362                         formatter % p_down->thread_id
1363                         % p_down->thread_division
1364                         % p_down->pair_thread_id
1365                         % p_down->accept_end_flag
1366                         % p_down->end_flag
1367                         % p_down->sorry_flag
1368                         % p_down->switch_flag
1369                         % p_down->last_status
1370                         % p_down->client_endpoint.address().to_string()
1371                         % p_down->client_endpoint.port()
1372                         % p_down->data_buffer
1373                         % p_down->data_buffer_size
1374                         % p_down->data_length
1375                         % p_down->data_offset
1376                         % p_down->current_message_rest_size
1377                         % p_down->data_state
1378                         % p_down->ip_hash;
1379                         putLogDebug(600042, formatter.str(), __FILE__, __LINE__);
1380                 }
1381                 /*------DEBUG LOG END------*/
1382
1383
1384                 boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
1385
1386                 session_thread_data_map[up_thread_id] = p_up;
1387                 session_thread_data_map[down_thread_id] = p_down;
1388
1389                 //set return status
1390                 status = ACCEPT;
1391                 //save last status
1392                 session_thread_data_map[up_thread_id]->last_status = status;
1393                 session_thread_data_map[down_thread_id]->last_status = REALSERVER_RECV;
1394         } catch (const std::bad_alloc &) {
1395                 std::cerr << "protocol_module_ip::handle_session_initialize() : exception : Could not allocate memory." << std::endl;
1396                 boost::format formatter("Could not allocate memory. thread id : %d.");
1397                 formatter % boost::this_thread::get_id();
1398                 putLogError(600027, formatter.str(), __FILE__, __LINE__);
1399                 status = FINALIZE;
1400         } catch (const std::exception &ex) {
1401                 std::cerr << "protocol_module_ip::handle_session_initialize() : exception : error = " << ex.what() << "." << std::endl;
1402                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1403                                         "handle_session_initialize() : exception : error = %s. thread id : %d.");
1404                 formatter % ex.what() % boost::this_thread::get_id();
1405                 putLogError(600028, formatter.str(), __FILE__, __LINE__);
1406                 status = FINALIZE;
1407         } catch (...) {
1408                 std::cerr << "protocol_module_ip::handle_session_initialize() : Unknown exception." << std::endl;
1409                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1410                                         "handle_session_initialize() : Unknown exception. thread id : %d.");
1411                 formatter % boost::this_thread::get_id();
1412                 putLogError(600029, formatter.str(), __FILE__, __LINE__);
1413                 status = FINALIZE;
1414         }
1415
1416         /*-------- DEBUG LOG --------*/
1417         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1418                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1419                                         "handle_session_initialize(const boost::thread::id up_thread_id, "
1420                                         "const boost::thread::id down_thread_id, "
1421                                         "const boost::asio::ip::tcp::endpoint& client_endpoint_tcp, "
1422                                         "const boost::asio::ip::udp::endpoint& client_endpoint_udp) : return_value = %d. "
1423                                         "thread id : %d.");
1424                 formatter % status % boost::this_thread::get_id();
1425                 putLogDebug(600043, formatter.str(), __FILE__, __LINE__);
1426         }
1427         /*------DEBUG LOG END------*/
1428
1429         return status;
1430 }
1431 //! called from session finalize use in upstream thread.
1432 //! @param[in]    upstream thread id.
1433 //! @param[in]    downstream thread id
1434 //! @return        session use EVENT mode.
1435 protocol_module_base::EVENT_TAG protocol_module_ip::handle_session_finalize(
1436         const boost::thread::id up_thread_id, const boost::thread::id down_thread_id)
1437 {
1438         /*-------- DEBUG LOG --------*/
1439         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1440                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1441                                         "handle_session_finalize(const boost::thread::id up_thread_id, "
1442                                         "const boost::thread::id down_thread_id) : "
1443                                         "up_thread_id = %d, down_thread_id = %d.");
1444                 formatter % up_thread_id % down_thread_id;
1445                 putLogDebug(600044, formatter.str(), __FILE__, __LINE__);
1446         }
1447         /*------DEBUG LOG END------*/
1448         EVENT_TAG status = STOP;
1449
1450         //session thread free
1451         try {
1452                 boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
1453
1454                 session_thread_data_map_it session_thread_data_it = session_thread_data_map.find(up_thread_id);
1455                 if (session_thread_data_it != session_thread_data_map.end()) {
1456                         thread_data_ptr p_up = session_thread_data_it->second;
1457                         /*-------- DEBUG LOG --------*/
1458                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1459                                 boost::format formatter("delete : address = &(%d).");
1460                                 formatter % static_cast<void *>(p_up->data_buffer);
1461                                 putLogDebug(600045, formatter.str(), __FILE__, __LINE__);
1462                         }
1463                         /*------DEBUG LOG END------*/
1464
1465                         delete p_up->data_buffer;
1466                         /*-------- DEBUG LOG --------*/
1467                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1468                                 boost::format formatter("delete : address = &(%d).");
1469                                 formatter % static_cast<void *>(p_up.get());
1470                                 putLogDebug(600046, formatter.str(), __FILE__, __LINE__);
1471                         }
1472                         /*------DEBUG LOG END------*/
1473
1474                         session_thread_data_map.erase(up_thread_id);
1475                 }
1476
1477                 session_thread_data_it = session_thread_data_map.find(down_thread_id);
1478                 if (session_thread_data_it != session_thread_data_map.end()) {
1479
1480                         thread_data_ptr p_down = session_thread_data_it->second;
1481                         /*-------- DEBUG LOG --------*/
1482                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1483                                 boost::format formatter("delete : address = &(%d).");
1484                                 formatter % static_cast<void *>(p_down->data_buffer);
1485                                 putLogDebug(600047, formatter.str(), __FILE__, __LINE__);
1486                         }
1487                         /*------DEBUG LOG END------*/
1488
1489                         delete p_down->data_buffer;
1490                         /*-------- DEBUG LOG --------*/
1491                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1492                                 boost::format formatter("delete : address = &(%d).");
1493                                 formatter % static_cast<void *>(p_down.get());
1494                                 putLogDebug(600048, formatter.str(), __FILE__, __LINE__);
1495                         }
1496                         /*------DEBUG LOG END------*/
1497
1498                         session_thread_data_map.erase(down_thread_id);
1499                 }
1500
1501                 //set return status
1502                 status = STOP;
1503         } catch (const std::exception &ex) {
1504                 std::cerr << "protocol_module_ip::handle_session_finalize() : exception : error = " << ex.what() << "." << std::endl;
1505                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1506                                         "handle_session_finalize() : exception : error = %s. thread id : %d.");
1507                 formatter % ex.what() % boost::this_thread::get_id();
1508                 putLogError(600030, formatter.str(), __FILE__, __LINE__);
1509                 status = STOP;
1510         } catch (...) {
1511                 std::cerr << "protocol_module_ip::handle_session_finalize() : Unknown exception." << std::endl;
1512                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1513                                         "handle_session_finalize() : "
1514                                         "Unknown exception. thread id : %d.");
1515                 formatter % boost::this_thread::get_id();
1516                 putLogError(600031, formatter.str(), __FILE__, __LINE__);
1517                 status = STOP;
1518         }
1519         /*-------- DEBUG LOG --------*/
1520         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1521                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1522                                         "handle_session_finalize(const boost::thread::id up_thread_id, "
1523                                         "const boost::thread::id down_thread_id) : return_value = %d. thread id : %d.");
1524                 formatter % status % boost::this_thread::get_id();
1525                 putLogDebug(600049, formatter.str(), __FILE__, __LINE__);
1526         }
1527         /*------DEBUG LOG END------*/
1528         return status;
1529 }
1530
1531 //! called from after session accept.in client socket use in upstream thread.
1532 //! @param[in]    upstream thread id.
1533 //! @return        session use EVENT mode.
1534 protocol_module_base::EVENT_TAG protocol_module_ip::handle_accept(const boost::thread::id thread_id)
1535 {
1536         /*-------- DEBUG LOG --------*/
1537         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1538                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1539                                         "handle_accept(const boost::thread::id thread_id) : thread_id = %d.");
1540                 formatter % thread_id;
1541                 putLogDebug(600050, formatter.str(), __FILE__, __LINE__);
1542         }
1543         /*------DEBUG LOG END------*/
1544
1545         EVENT_TAG status = FINALIZE;
1546         thread_data_ptr session_data_ptr;
1547         session_thread_data_map_it session_thread_it;
1548
1549         try {
1550                 {
1551                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
1552
1553                         session_thread_it = session_thread_data_map.find(thread_id);
1554                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
1555                                 boost::format formatter("Invalid thread id. thread id : %d.");
1556                                 formatter % boost::this_thread::get_id();
1557                                 putLogError(600032, formatter.str(), __FILE__, __LINE__);
1558                                 throw - 1;
1559                         }
1560
1561                         session_data_ptr = session_thread_it->second;
1562                 }
1563
1564                 //set accept end flag ON
1565                 session_data_ptr->accept_end_flag = ACCEPT_END_FLAG_ON;
1566
1567                 /*-------- DEBUG LOG --------*/
1568                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1569                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1570                                                 "handle_accept(const boost::thread::id thread_id) : ACCEPT_END_FLAG_ON. thread id : %d.");
1571                         formatter % boost::this_thread::get_id();
1572                         putLogDebug(600051, formatter.str(), __FILE__, __LINE__);
1573                 }
1574                 /*------DEBUG LOG END------*/
1575                 //sorry flag on
1576                 if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
1577                         //set return status
1578                         status = SORRYSERVER_SELECT;
1579                 }
1580                 //sorry flag off
1581                 else {
1582                         //set return status
1583                         status = REALSERVER_SELECT;
1584                 }
1585
1586                 //set last status
1587                 session_data_ptr->last_status = status;
1588         } catch (int e) {
1589                 /*-------- DEBUG LOG --------*/
1590                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1591                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1592                                                 "handle_accept() : catch exception e = %d. thread id : %d.");
1593                         formatter % e % boost::this_thread::get_id();
1594                         putLogDebug(600052, formatter.str(), __FILE__, __LINE__);
1595                 }
1596                 /*------DEBUG LOG END------*/
1597                 status = FINALIZE;
1598         } catch (const std::exception &ex) {
1599                 std::cerr << "protocol_module_ip::handle_accept() : exception : error = " << ex.what() << "." << std::endl;
1600                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1601                                         "handle_accept() : exception : error = %s. thread id : %d.");
1602                 formatter % ex.what() % boost::this_thread::get_id();
1603                 putLogError(600033, formatter.str(), __FILE__, __LINE__);
1604                 status = FINALIZE;
1605         } catch (...) {
1606                 std::cerr << "protocol_module_ip::handle_accept() : Unknown exception." << std::endl;
1607                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
1608                                         "protocol_module_ip::handle_accept() : "
1609                                         "Unknown exception. thread id : %d.");
1610                 formatter % boost::this_thread::get_id();
1611                 putLogError(600034, formatter.str(), __FILE__, __LINE__);
1612                 status = FINALIZE;
1613         }
1614
1615         /*-------- DEBUG LOG --------*/
1616         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1617                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1618                                         "handle_accept(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
1619                 formatter % status % boost::this_thread::get_id();
1620                 putLogDebug(600053, formatter.str(), __FILE__, __LINE__);
1621         }
1622         /*------DEBUG LOG END------*/
1623
1624         return status;
1625 }
1626
1627 //! called from after session recv in client socket. use in upstream thread.
1628 //! @param[in]    upstream thread id
1629 //! @param[in]    receive buffer reference.
1630 //! @param[in]    receive length
1631 //! @return        session use EVENT mode.
1632 protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_recv(const boost::thread::id thread_id,
1633                 const boost::array<char, MAX_BUFFER_SIZE>& recvbuffer, const size_t recvlen)
1634 {
1635
1636         /*-------- DEBUG LOG --------*/
1637         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1638                 size_t buffer_size = recvbuffer.size() < recvlen ? recvbuffer.size() : recvlen;
1639                 std::string buffer;
1640                 dump_memory(recvbuffer.data(), buffer_size, buffer);
1641                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1642                                         "handle_client_recv(const boost::thread::id thread_id, "
1643                                         "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
1644                                         "const size_t recvlen) : thread_id = %d, recvbuffer = %s, recvlen = %d.");
1645                 formatter % thread_id % buffer % recvlen;
1646                 putLogDebug(600054, formatter.str(), __FILE__, __LINE__);
1647         }
1648         /*------DEBUG LOG END------*/
1649
1650         EVENT_TAG status                = FINALIZE;
1651         bool find_ret                    = false;
1652         size_t http_header_offset            = 0;
1653         size_t http_header_len                = 0;
1654         size_t http_header_content_length_offset    = 0;
1655         size_t http_header_content_length_len        = 0;
1656         int content_length_value            = 0;
1657         const size_t CR_LF_LEN                = strlen("\r\n");
1658         const size_t CR_LF_CR_LF_LEN            = strlen("\r\n\r\n");
1659         session_thread_data_map_it            session_thread_it;
1660         thread_data_ptr                    session_data_ptr;
1661         http_utility::CHECK_RESULT_TAG             check_ret;
1662
1663         std::string content_length;
1664         cmatch regex_ret;
1665         cregex content_length_regex = icase("Content-Length") >> ":" >> *~_d >> (s1 = +_d) >> *~_d;
1666
1667         //parameter check
1668         if (unlikely(recvlen > recvbuffer.size())) {
1669                 std::cerr << "protocol_module_ip::handle_client_recv() : Data size bigger than buffer size." << std::endl;
1670                 boost::format formatter("Data size bigger than buffer size. thread id : %d.");
1671                 formatter % boost::this_thread::get_id();
1672                 putLogError(600035, formatter.str(), __FILE__, __LINE__);
1673
1674                 /*-------- DEBUG LOG --------*/
1675                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1676                         boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1677                                                 "handle_client_recv(const boost::thread::id thread_id, "
1678                                                 "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
1679                                                 "const size_t recvlen) : return_value = %d. thread id : %d.");
1680                         formatter % FINALIZE % boost::this_thread::get_id();
1681                         putLogDebug(600055, formatter.str(), __FILE__, __LINE__);
1682                 }
1683                 /*------DEBUG LOG END------*/
1684                 return status;
1685         }
1686
1687         try {
1688                 {
1689                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
1690
1691                         session_thread_it = session_thread_data_map.find(thread_id);
1692                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
1693
1694                                 boost::format formatter("Invalid thread id. thread id : %d.");
1695                                 formatter % boost::this_thread::get_id();
1696                                 putLogError(600036, formatter.str(), __FILE__, __LINE__);
1697                                 throw - 1;
1698                         }
1699
1700                         session_data_ptr = session_thread_it->second;
1701                 }
1702
1703                 //end flag on
1704                 if (session_data_ptr->end_flag == END_FLAG_ON) {
1705                         //set return status
1706                         status = CLIENT_RECV;
1707                 }
1708                 //end flag off
1709                 else {
1710                         //copy data from recvbuffer
1711                         if (!get_data_from_recvbuffer(session_data_ptr, recvbuffer, recvlen)) {
1712                                 //copy failed
1713                                 std::cerr << "protocol_module_ip::handle_client_recv() : Data size bigger than buffer size." << std::endl;
1714                                 boost::format formatter("Data size bigger than buffer size. thread id : % id.");
1715                                 formatter % boost::this_thread::get_id();
1716                                 putLogError(600037, formatter.str(), __FILE__, __LINE__);
1717                                 status = FINALIZE;
1718                         } else {
1719                                 if (statistic == COLLECT_STATS_OFF && forwarded_for == FORWARDED_FOR_OFF && session_data_ptr->sorry_flag == SORRY_FLAG_OFF) {
1720                                         session_data_ptr->data_state = UNKNOWN;
1721                                 }
1722                                 //data state is HTTP_START
1723                                 if (session_data_ptr->data_state == HTTP_START) {
1724                                         //search http header
1725                                         find_ret = http_utility::find_http_header_all(session_data_ptr->data_buffer + session_data_ptr->data_offset,
1726                                                         session_data_ptr->data_length,
1727                                                         http_header_offset,
1728                                                         http_header_len
1729                                                                                      );
1730
1731                                         /*-------- DEBUG LOG --------*/
1732                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1733                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1734                                                                         "handle_client_recv() : call find_http_header_all : "
1735                                                                         "return_value = %d. thread id : %d.");
1736                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
1737                                                 putLogDebug(600056, formatter.str(), __FILE__, __LINE__);
1738                                         }
1739                                         /*------DEBUG LOG END------*/
1740
1741                                         //search http header result is NG
1742                                         if (!find_ret) {
1743                                                 //data size bigger than max buffer size
1744                                                 if (session_data_ptr->data_length >= MAX_IP_MODULE_BUFFER_SIZE - recvbuffer.size()) {
1745                                                         //set data state UNKNOWN
1746                                                         session_data_ptr->data_state = UNKNOWN;
1747                                                         //set current message rest size
1748                                                         session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
1749                                                 }
1750                                         }
1751                                         //search http header result is OK
1752                                         else {
1753                                                 //check http method and version
1754                                                 check_ret = http_utility::check_http_method_and_version(session_data_ptr->data_buffer,
1755                                                                 session_data_ptr->data_length);
1756                                                 /*-------- DEBUG LOG --------*/
1757                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1758                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1759                                                                                 "handle_client_recv() : call check_http_method_and_version : "
1760                                                                                 "return_value = %d. thread id : %d.");
1761                                                         formatter % check_ret % boost::this_thread::get_id();
1762                                                         putLogDebug(600057, formatter.str(), __FILE__, __LINE__);
1763                                                 }
1764                                                 /*------DEBUG LOG END------*/
1765
1766                                                 //check http method and version result is NG
1767                                                 if (check_ret == http_utility::CHECK_NG) {
1768                                                         //set data state UNKNOWN
1769                                                         session_data_ptr->data_state = UNKNOWN;
1770                                                         //set current message rest size
1771                                                         session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
1772                                                 }
1773                                                 //check http method and version result is OK
1774                                                 else {
1775                                                         //search Content_Length header
1776                                                         find_ret = http_utility::find_http_header_content_length(session_data_ptr->data_buffer + session_data_ptr->data_offset,
1777                                                                         session_data_ptr->data_length,
1778                                                                         http_header_content_length_offset,
1779                                                                         http_header_content_length_len);
1780                                                         /*-------- DEBUG LOG --------*/
1781                                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1782                                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1783                                                                                         "handle_client_recv() : call find_http_header_content_length : "
1784                                                                                         "return_value = %d. thread id : %d.");
1785                                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
1786                                                                 putLogDebug(600058, formatter.str(), __FILE__, __LINE__);
1787                                                         }
1788                                                         /*------DEBUG LOG END------*/
1789
1790                                                         //search Content_Length result is OK
1791                                                         if (find_ret) {
1792                                                                 //set content length string
1793                                                                 content_length.assign(session_data_ptr->data_buffer + session_data_ptr->data_offset + http_header_content_length_offset,
1794                                                                                       http_header_content_length_len);
1795                                                                 find_ret = regex_search(content_length.c_str(), regex_ret, content_length_regex);
1796
1797                                                                 //"content-length: ddd\r\n"
1798                                                                 if (find_ret) {
1799                                                                         content_length = content_length.substr(
1800                                                                                                  regex_ret.position(1),
1801                                                                                                  regex_ret.length(1));
1802
1803                                                                         //set content length value
1804                                                                         content_length_value = boost::lexical_cast<int>(content_length);
1805                                                                 }
1806
1807                                                                 //http_header context is "\r\n\r\n" only
1808                                                                 if (http_header_len == 0) {
1809                                                                         //set current message rest size
1810                                                                         session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + content_length_value + CR_LF_LEN;
1811                                                                 } else {
1812                                                                         //set current message rest size
1813                                                                         session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + content_length_value + CR_LF_CR_LF_LEN;
1814                                                                 }
1815                                                         }
1816                                                         //search Content_Length result is NG
1817                                                         else {
1818                                                                 //http_header context is "\r\n\r\n" only
1819                                                                 if (http_header_len == 0) {
1820                                                                         //set current message rest size
1821                                                                         session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + CR_LF_LEN;
1822                                                                 } else {
1823                                                                         //set current message rest size
1824                                                                         session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + CR_LF_CR_LF_LEN;
1825                                                                 }
1826
1827                                                         }
1828
1829                                                         //increment http statistics
1830                                                         increment_stats(session_data_ptr->data_buffer + session_data_ptr->data_offset);
1831                                                         /*-------- DEBUG LOG --------*/
1832                                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1833                                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1834                                                                                         "handle_client_recv() : call increment_stats : thread id : %d.");
1835                                                                 formatter % boost::this_thread::get_id();
1836                                                                 putLogDebug(600228, formatter.str(), __FILE__, __LINE__);
1837                                                         }
1838                                                         /*------DEBUG LOG END------*/
1839
1840                                                         //set data state HTTP_HEADER
1841                                                         session_data_ptr->data_state = HTTP_HEADER;
1842
1843                                                 }
1844                                         }
1845                                 }
1846                                 //data state is UNKNOWN
1847                                 else if (session_data_ptr->data_state == UNKNOWN) {
1848                                         //set current message rest size
1849                                         session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
1850                                 } else {
1851                                         //none
1852                                 }
1853
1854                                 //data state is HTTP_START
1855                                 if (session_data_ptr->data_state == HTTP_START) {
1856                                         status = CLIENT_RECV;
1857                                 }
1858                                 //data state is not HTTP_START
1859                                 else {
1860                                         //sorry flag is on
1861                                         if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
1862                                                 //set return status
1863                                                 status = SORRYSERVER_CONNECT;
1864                                         }
1865                                         //sorry flag is off
1866                                         else {
1867                                                 //set return status
1868                                                 status = REALSERVER_CONNECT;
1869                                         }
1870                                 }
1871                         }
1872                 }
1873
1874                 //set last status
1875                 session_data_ptr->last_status = status;
1876         } catch (int e) {
1877                 /*-------- DEBUG LOG --------*/
1878                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1879                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1880                                                 "handle_client_recv() : catch exception e = %d. thread id : %d.");
1881                         formatter % e % boost::this_thread::get_id();
1882                         putLogDebug(600059, formatter.str(), __FILE__, __LINE__);
1883                 }
1884                 /*------DEBUG LOG END------*/
1885                 status = FINALIZE;
1886         } catch (const boost::bad_lexical_cast &) {
1887                 std::cerr << "protocol_module_ip::handle_client_recv() : exception : " <<  "Content_Length field's value is invalid." << std::endl;
1888                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_recv() : "
1889                                         "Content_Length field's value is invalid. thread id : %d.");
1890                 formatter % boost::this_thread::get_id();
1891                 putLogError(600038, formatter.str(), __FILE__, __LINE__);
1892                 status = FINALIZE;
1893         } catch (const std::exception &ex) {
1894                 std::cerr << "protocol_module_ip::handle_client_recv() : exception : error = " << ex.what() << "." << std::endl;
1895                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1896                                         "handle_client_recv() : exception : error = %s. thread id : %d.");
1897                 formatter % ex.what() % boost::this_thread::get_id();
1898                 putLogError(600039, formatter.str(), __FILE__, __LINE__);
1899                 status = FINALIZE;
1900         } catch (...) {
1901                 std::cerr << "protocol_module_ip::handle_client_recv() : Unknown exception." << std::endl;
1902                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
1903                                         "protocol_module_ip::handle_client_recv() : "
1904                                         "Unknown exception. thread id : %d.");
1905                 formatter % boost::this_thread::get_id();
1906                 putLogError(600040, formatter.str(), __FILE__, __LINE__);
1907                 status = FINALIZE;
1908         }
1909
1910         /*-------- DEBUG LOG --------*/
1911         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1912                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1913                                         "handle_client_recv(const boost::thread::id thread_id, "
1914                                         "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
1915                                         "const size_t recvlen) : return_value = %d. thread id : %d.");
1916                 formatter % status % boost::this_thread::get_id();
1917                 putLogDebug(600060, formatter.str(), __FILE__, __LINE__);
1918         }
1919         /*------DEBUG LOG END------*/
1920
1921         return status;
1922 }
1923
1924 //! called from after realserver select.use in upstream thread.
1925 //! @param[in]    upstream thread id
1926 //! @param[out]    realserver TCP endpoint
1927 //! @return        session use EVENT mode.
1928 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_select(
1929         const boost::thread::id thread_id, boost::asio::ip::tcp::endpoint &rs_endpoint)
1930 {
1931
1932         /*-------- DEBUG LOG --------*/
1933         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1934                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1935                                         "handle_realserver_select(const boost::thread::id thread_id, "
1936                                         "boost::asio::ip::tcp::endpoint& rs_endpoint) : "
1937                                         "thread_id = %d, rs_endpoint = [%s]:%d.");
1938                 formatter % thread_id % rs_endpoint.address().to_string() % rs_endpoint.port();
1939                 putLogDebug(600061, formatter.str(), __FILE__, __LINE__);
1940         }
1941         /*------DEBUG LOG END------*/
1942
1943         EVENT_TAG status = FINALIZE;
1944         boost::asio::ip::tcp::endpoint init_endpoint;
1945         thread_data_ptr session_data_ptr;
1946         session_thread_data_map_it session_thread_it;
1947         session_thread_data_map_it session_thread_it_end;
1948         realserverlist_type::iterator    rs_list_itr;
1949
1950         if (unlikely(schedule_tcp.empty())) {
1951                 std::cerr << "protocol_module_ip::handle_realserver_select() : Schedule_tcp function is empty." << std::endl;
1952                 boost::format formatter("Schedule_tcp function is empty. thread id : %d.");
1953                 formatter % boost::this_thread::get_id();
1954                 putLogError(600041, formatter.str(), __FILE__, __LINE__);
1955
1956                 /*-------- DEBUG LOG --------*/
1957                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1958                         boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1959                                                 "handle_realserver_select(const boost::thread::id thread_id, "
1960                                                 "boost::asio::ip::tcp::endpoint& rs_endpoint)"
1961                                                 " : return_value = %d. thread id : %d.");
1962                         formatter % FINALIZE % boost::this_thread::get_id();
1963                         putLogDebug(600062, formatter.str(), __FILE__, __LINE__);
1964                 }
1965                 /*------DEBUG LOG END------*/
1966                 return FINALIZE;
1967         }
1968
1969
1970         try {
1971                 {
1972                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
1973
1974                         session_thread_it = session_thread_data_map.find(thread_id);
1975                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
1976                                 boost::format formatter("Invalid thread id. thread id : %d.");
1977                                 formatter % boost::this_thread::get_id();
1978                                 putLogError(600042, formatter.str(), __FILE__, __LINE__);
1979                                 throw - 1;
1980                         }
1981
1982                         session_data_ptr = session_thread_it->second;
1983                 }
1984
1985                 //initialize realserver endpoint
1986                 rs_endpoint = init_endpoint;
1987
1988                 boost::mutex::scoped_lock lock(session_data_mutex);
1989
1990                 //get endpoint data from the ip data
1991                 int ret = ip_data_processor->get_endpoint_from_session_data(session_data_ptr->ip_hash,
1992                                 rs_endpoint);
1993
1994                 /*-------- DEBUG LOG --------*/
1995                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1996                         boost::format formatter("function : protocol_module_base::EVENT_TAG "
1997                                                 "protocol_module_ip::handle_realserver_select() : "
1998                                                 "get_endpoint_from_session_data() end. thread id : %d.");
1999                         formatter % boost::this_thread::get_id();
2000                         putLogDebug(600063, formatter.str(), __FILE__, __LINE__);
2001                 }
2002                 /*------DEBUG LOG END------*/
2003
2004                 //endpoint is matched
2005                 if (ret == 0) {
2006                         int is_match = 0;
2007                         //find the rs_endpoint in rs_list
2008                         {
2009                                 rs_list_scoped_lock scoped_lock(rs_list_lock, rs_list_unlock);
2010
2011                                 rs_list_itr = rs_list_begin();
2012
2013                                 while (rs_list_itr != rs_list_end()) {
2014
2015                                         if (rs_list_itr->tcp_endpoint == rs_endpoint) {
2016                                                 if (rs_list_itr->weight != 0) {
2017                                                         is_match = 1;
2018                                                 }
2019                                                 break;
2020                                         }
2021
2022                                         rs_list_itr = rs_list_next(rs_list_itr);
2023                                 }
2024                         }
2025
2026                         //endpoint is matched in the list
2027                         if (is_match) {
2028                                 //set return status
2029                                 status = REALSERVER_CONNECT;
2030                         }
2031                         //endpoint is not matched in the list
2032                         else {
2033                                 //if reschedule is on then try multi times connect
2034                                 if (reschedule == 1) {
2035                                         // init rs_endpoint
2036                                         rs_endpoint = init_endpoint;
2037                                         {
2038                                                 rs_list_scoped_lock scoped_lock(rs_list_lock, rs_list_unlock);
2039                                                 schedule_tcp(thread_id, rs_list_begin, rs_list_end, rs_list_next, rs_endpoint);
2040                                         }
2041
2042                                         /*-------- DEBUG LOG --------*/
2043                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2044                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2045                                                                         "handle_realserver_select() : call schedule_tcp : "
2046                                                                         "rs_endpoint = [%s]:%d. thread id : %d.");
2047                                                 formatter % rs_endpoint.address().to_string() % rs_endpoint.port() % boost::this_thread::get_id();
2048                                                 putLogDebug(600064, formatter.str(), __FILE__, __LINE__);
2049                                         }
2050                                         /*------DEBUG LOG END------*/
2051
2052                                         //get the endpoint by schedule successfully
2053                                         if (init_endpoint != rs_endpoint) {
2054                                                 time_t init_time = 0;
2055
2056                                                 //write data to session table
2057                                                 ip_data_processor->write_session_data(session_data_ptr->ip_hash, rs_endpoint, init_time);
2058                                                 /*-------- DEBUG LOG --------*/
2059                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2060                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG "
2061                                                                                 "protocol_module_ip::handle_realserver_select() : "
2062                                                                                 "write_session_data() end. thread id : %d.");
2063                                                         formatter % boost::this_thread::get_id();
2064                                                         putLogDebug(600065, formatter.str(), __FILE__, __LINE__);
2065                                                 }
2066                                                 /*------DEBUG LOG END------*/
2067
2068                                                 //set return status
2069                                                 status = REALSERVER_CONNECT;
2070                                         }
2071                                         //get the endpoint by schedule unsuccessfully
2072                                         else {
2073                                                 session_data_ptr->sorry_flag = SORRY_FLAG_ON;
2074                                                 /*-------- DEBUG LOG --------*/
2075                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2076                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2077                                                                                 "handle_realserver_select()"
2078                                                                                 " : SORRY_FLAG_ON. thread id : %d.");
2079                                                         formatter % boost::this_thread::get_id();
2080                                                         putLogDebug(600066, formatter.str(), __FILE__, __LINE__);
2081                                                 }
2082                                                 /*------DEBUG LOG END------*/
2083
2084                                                 //set return status
2085                                                 status = SORRYSERVER_SELECT;
2086                                         }
2087                                 }
2088                                 //reschedule is off
2089                                 else {
2090                                         //set return status
2091                                         status = FINALIZE;
2092                                 }
2093                         }
2094                 }
2095                 //endpoint is not matched
2096                 else {
2097                         // init rs_endpoint
2098                         rs_endpoint = init_endpoint;
2099
2100                         //call schedule_module's schedule function, get realserver endpoint
2101                         {
2102                                 rs_list_scoped_lock scoped_lock(rs_list_lock, rs_list_unlock);
2103                                 schedule_tcp(thread_id, rs_list_begin, rs_list_end, rs_list_next, rs_endpoint);
2104                         }
2105
2106                         /*-------- DEBUG LOG --------*/
2107                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2108                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2109                                                         "handle_realserver_select() : call schedule_tcp : "
2110                                                         "rs_endpoint = [%s]:%d. thread id : %d.");
2111                                 formatter % rs_endpoint.address().to_string() % rs_endpoint.port() % boost::this_thread::get_id();
2112                                 putLogDebug(600067, formatter.str(), __FILE__, __LINE__);
2113                         }
2114                         /*------DEBUG LOG END------*/
2115
2116                         //get the endpoint by schedule successfully
2117                         if (init_endpoint != rs_endpoint) {
2118                                 time_t init_time = 0;
2119
2120                                 //write data to session table
2121                                 ip_data_processor->write_session_data(session_data_ptr->ip_hash, rs_endpoint, init_time);
2122                                 /*-------- DEBUG LOG --------*/
2123                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2124                                         boost::format formatter("function : protocol_module_base::EVENT_TAG "
2125                                                                 "protocol_module_ip::handle_realserver_select() : "
2126                                                                 "write_session_data() end. thread id : %d.");
2127                                         formatter % boost::this_thread::get_id();
2128                                         putLogDebug(600068, formatter.str(), __FILE__, __LINE__);
2129                                 }
2130                                 /*------DEBUG LOG END------*/
2131
2132                                 //set return status
2133                                 status = REALSERVER_CONNECT;
2134                         }
2135                         //get the endpoint by schedule unsuccessfully
2136                         else {
2137                                 session_data_ptr->sorry_flag = SORRY_FLAG_ON;
2138                                 /*-------- DEBUG LOG --------*/
2139                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2140                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2141                                                                 "handle_realserver_select()"
2142                                                                 " : SORRY_FLAG_ON. thread id : %d.");
2143                                         formatter % boost::this_thread::get_id();
2144                                         putLogDebug(600069, formatter.str(), __FILE__, __LINE__);
2145                                 }
2146                                 /*------DEBUG LOG END------*/
2147                                 //set return status
2148                                 status = SORRYSERVER_SELECT;
2149
2150                         }
2151                 }
2152
2153                 //set last status
2154                 session_data_ptr->last_status = status;
2155         } catch (int e) {
2156                 /*-------- DEBUG LOG --------*/
2157                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2158                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2159                                                 "handle_realserver_select() : catch exception e = %d. thread id : %d.");
2160                         formatter % e % boost::this_thread::get_id();
2161                         putLogDebug(600070, formatter.str(), __FILE__, __LINE__);
2162                 }
2163                 /*------DEBUG LOG END------*/
2164                 status = FINALIZE;
2165         } catch (const std::exception &ex) {
2166                 std::cerr << "protocol_module_ip::handle_realserver_select() : exception : error = " << ex.what() << "." << std::endl;
2167                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2168                                         "handle_realserver_select() : exception : error = %s. thread id : %d.");
2169                 formatter % ex.what() % boost::this_thread::get_id();
2170                 putLogError(600043, formatter.str(), __FILE__, __LINE__);
2171                 status = FINALIZE;
2172         } catch (...) {
2173                 std::cerr << "protocol_module_ip::handle_realserver_select() : Unknown exception." << std::endl;
2174                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
2175                                         "protocol_module_ip::handle_realserver_select() : "
2176                                         "Unknown exception. thread id : %d.");
2177                 formatter % boost::this_thread::get_id();
2178                 putLogError(600044, formatter.str(), __FILE__, __LINE__);
2179                 status = FINALIZE;
2180         }
2181
2182         /*-------- DEBUG LOG --------*/
2183         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2184                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2185                                         "handle_realserver_select(const boost::thread::id thread_id, "
2186                                         "boost::asio::ip::tcp::endpoint& rs_endpoint)"
2187                                         " : return_value = %d. thread id : %d.");
2188                 formatter % status % boost::this_thread::get_id();
2189                 putLogDebug(600071, formatter.str(), __FILE__, __LINE__);
2190         }
2191         /*------DEBUG LOG END------*/
2192         return status;
2193 }
2194
2195 //! called from after realserver select
2196 //! @param[in]    upstream thread id
2197 //! @param[out]    realserver UDP endpoint
2198 //! @param[out]    send buffer reference
2199 //! @param[out]    send data length
2200 //! @return        session use EVENT mode.
2201 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_select(
2202         const boost::thread::id thread_id, boost::asio::ip::udp::endpoint &rs_endpoint, boost::array < char,
2203         MAX_BUFFER_SIZE > & sendbuffer, size_t &datalen)
2204 {
2205         /*-------- DEBUG LOG --------*/
2206         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2207                 boost::format formatter("in/out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2208                                         "handle_realserver_select(const boost::thread::id thread_id, "
2209                                         "boost::asio::ip::udp::endpoint& rs_endpoint, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
2210                                         "size_t& datalen) : "
2211                                         "return_value = %d. thread id : %d.");
2212                 formatter % STOP % boost::this_thread::get_id();
2213                 putLogDebug(600072, formatter.str(), __FILE__, __LINE__);
2214         }
2215         /*------DEBUG LOG END------*/
2216         return STOP;
2217 }
2218 //! called from after realserver connect
2219 //! @param[in]    upstream thread id
2220 //! @param[out]    sendbuffer reference
2221 //! @param[out]    send data length
2222 //! @return        session use EVENT mode.
2223 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_connect(
2224         const boost::thread::id thread_id, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen)
2225 {
2226         /*-------- DEBUG LOG --------*/
2227         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2228                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2229                                         "handle_realserver_connect(const boost::thread::id thread_id, "
2230                                         "boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t& datalen) : "
2231                                         "thread_id = %d.");
2232                 formatter % thread_id;
2233                 putLogDebug(600073, formatter.str(), __FILE__, __LINE__);
2234         }
2235         /*------DEBUG LOG END------*/
2236
2237         EVENT_TAG status            = FINALIZE;
2238         size_t send_possible_size        = 0;
2239         size_t x_forwarded_for_insert_pos   = 0;
2240         thread_data_ptr                session_data_ptr;
2241         std::pair<char *, size_t>        buffer_element;
2242         std::string                x_forwarded_for_context;
2243
2244         try {
2245                 session_thread_data_map_mutex.lock();
2246
2247                 //thread id check
2248                 session_thread_data_map_it session_thread_it = session_thread_data_map.find(thread_id);
2249                 if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
2250                         boost::format formatter("Invalid thread id. thread id : %d.");
2251                         formatter % boost::this_thread::get_id();
2252                         putLogError(600045, formatter.str(), __FILE__, __LINE__);
2253                         session_thread_data_map_mutex.unlock();
2254                         throw - 1;
2255                 }
2256
2257                 session_data_ptr = session_thread_it->second;
2258
2259                 send_possible_size = std::min(session_data_ptr->current_message_rest_size,
2260                                               session_data_ptr->data_length
2261                                              );
2262                 session_thread_data_map_mutex.unlock();
2263
2264                 //buffer sequence is empty
2265                 if (session_data_ptr->buffer_sequence.empty()) {
2266                         //data state is HTTP_HEADER
2267                         if (session_data_ptr->data_state == HTTP_HEADER) {
2268                                 //forwarded_for flag is on
2269                                 if (forwarded_for == FORWARDED_FOR_ON) {
2270                                         //search X-Forwarded-For header
2271                                         create_x_forwarded_for(session_data_ptr->client_endpoint.address().to_string(),
2272                                                                session_data_ptr->data_buffer + session_data_ptr->data_offset,
2273                                                                session_data_ptr->data_length,
2274                                                                x_forwarded_for_insert_pos,
2275                                                                x_forwarded_for_context);
2276
2277                                         //put buffer data to buffer_sequence
2278                                         buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset;
2279                                         buffer_element.second = x_forwarded_for_insert_pos;
2280                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2281
2282                                         session_data_ptr->forwarded_for_buffer.assign(0);
2283
2284                                         /*-------- DEBUG LOG --------*/
2285                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2286                                                 std::string datadump;
2287                                                 dump_memory(x_forwarded_for_context.c_str(),
2288                                                             x_forwarded_for_context.size(), datadump);
2289                                                 boost::format formatter(
2290                                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2291                                                         "handle_realserver_connect() : before memcpy (data dump) : "
2292                                                         "data begin = 0, data_size = %d, data = %s");
2293                                                 formatter %  x_forwarded_for_context.size() % datadump;
2294                                                 putLogDebug(600074, formatter.str(), __FILE__, __LINE__);
2295                                         }
2296                                         /*------DEBUG LOG END------*/
2297
2298                                         memcpy(session_data_ptr->forwarded_for_buffer.data(),
2299                                                x_forwarded_for_context.c_str(),
2300                                                x_forwarded_for_context.size());
2301
2302                                         /*-------- DEBUG LOG --------*/
2303                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2304                                                 std::string datadump;
2305                                                 dump_memory(x_forwarded_for_context.c_str(),
2306                                                             x_forwarded_for_context.size(), datadump);
2307                                                 boost::format formatter(
2308                                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2309                                                         "handle_realserver_connect() : after memcpy (data dump) : "
2310                                                         "data begin = 0, data_size = %d, data = %s");
2311                                                 formatter % x_forwarded_for_context.size() % datadump;
2312                                                 putLogDebug(600075, formatter.str(), __FILE__, __LINE__);
2313                                         }
2314                                         /*------DEBUG LOG END------*/
2315
2316                                         //set buffer's position
2317                                         buffer_element.first = session_data_ptr->forwarded_for_buffer.data();
2318                                         buffer_element.second = x_forwarded_for_context.size();
2319
2320                                         //set data to buffer_sequence
2321                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2322
2323                                         //set buffer's position
2324                                         buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset + x_forwarded_for_insert_pos;
2325                                         buffer_element.second = send_possible_size - x_forwarded_for_insert_pos;
2326
2327                                         //set data to buffer_sequence
2328                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2329                                 }
2330                                 //forwarded_for flag is off
2331                                 else {
2332                                         //set buffer's position
2333                                         buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset;
2334                                         buffer_element.second = send_possible_size;
2335
2336                                         //set data to buffer_sequence
2337                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2338                                 }
2339                                 session_data_ptr->data_state = HTTP_BODY;
2340                         }
2341                         //data state is not HTTP_HEADER
2342                         else {
2343
2344                                 buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset;
2345                                 buffer_element.second = send_possible_size;
2346
2347                                 //set data to buffer_sequence
2348                                 session_data_ptr->buffer_sequence.push_back(buffer_element);
2349
2350                         }
2351                 }
2352
2353                 //put buffer_sequence data into sendbuffer
2354                 put_data_into_sendbuffer(session_data_ptr, sendbuffer, datalen);
2355
2356                 //set return status
2357                 status = REALSERVER_SEND;
2358
2359                 //set last status
2360                 session_data_ptr->last_status = status;
2361         } catch (int e) {
2362                 /*-------- DEBUG LOG --------*/
2363                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2364                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2365                                                 "handle_realserver_connect() : catch exception e = %d. thread id : %d.");
2366                         formatter % e % boost::this_thread::get_id();
2367                         putLogDebug(600076, formatter.str(), __FILE__, __LINE__);
2368                 }
2369                 /*------DEBUG LOG END------*/
2370
2371                 //set return status
2372                 status = FINALIZE;
2373         } catch (std::exception &ex) {
2374                 std::cerr << "protocol_module_ip::handle_realserver_connect() : exception : error = " << ex.what() << "." << std::endl;
2375                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2376                                         "handle_realserver_connect() : exception : error = %s. thread id : %d.");
2377                 formatter % ex.what() % boost::this_thread::get_id();
2378                 putLogError(600046, formatter.str(), __FILE__, __LINE__);
2379
2380                 //set return status
2381                 status = FINALIZE;
2382         } catch (...) {
2383                 std::cerr << "protocol_module_ip::handle_realserver_connect() : Unknown exception." << std::endl;
2384                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2385                                         "handle_realserver_connect() : Unknown exception. thread id : %d.");
2386                 formatter % boost::this_thread::get_id();
2387                 putLogError(600047, formatter.str(), __FILE__, __LINE__);
2388
2389                 //set return status
2390                 status = FINALIZE;
2391         }
2392
2393         /*-------- DEBUG LOG --------*/
2394         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2395                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2396                                         "handle_realserver_connect(const boost::thread::id thread_id, "
2397                                         "boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
2398                                         "size_t& datalen) : return_value = %d. thread id : %d.");
2399                 formatter % status % boost::this_thread::get_id();
2400                 putLogDebug(600077, formatter.str(), __FILE__, __LINE__);
2401         }
2402         /*------DEBUG LOG END------*/
2403
2404         return status;
2405 }
2406
2407 //! called from after realserver connection fail
2408 //! @param[in]    upstream thread id
2409 //! @param[in]    fail realserver endpoint reference
2410 //! @return        session use EVENT mode.
2411 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_connection_fail(
2412         const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &rs_endpoint)
2413 {
2414         /*-------- DEBUG LOG --------*/
2415         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2416                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2417                                         "handle_realserver_connection_fail(const boost::thread::id thread_id, "
2418                                         "const boost::asio::ip::tcp::endpoint& rs_endpoint) : "
2419                                         "thread_id = %d, rs_endpoint = [%s]:%d.");
2420                 formatter % thread_id % rs_endpoint.address().to_string() % rs_endpoint.port();
2421                 putLogDebug(600078, formatter.str(), __FILE__, __LINE__);
2422         }
2423         /*------DEBUG LOG END------*/
2424
2425         EVENT_TAG status = FINALIZE;
2426         thread_data_ptr session_data_ptr;
2427         session_thread_data_map_it session_thread_it;
2428
2429         try {
2430                 boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
2431
2432                 session_thread_it = session_thread_data_map.find(thread_id);
2433                 if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
2434                         boost::format formatter("Invalid thread id. thread id : %d.");
2435                         formatter % boost::this_thread::get_id();
2436                         putLogError(600048, formatter.str(), __FILE__, __LINE__);
2437                         throw - 1;
2438                 }
2439
2440                 session_data_ptr = session_thread_it->second;
2441
2442                 //set return status
2443                 status = CLIENT_DISCONNECT;
2444
2445                 //set last status
2446                 session_data_ptr->last_status = status;
2447         } catch (int e) {
2448                 /*-------- DEBUG LOG --------*/
2449                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2450                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2451                                                 "handle_realserver_connection_fail() : catch exception e = %d. thread id : %d.");
2452                         formatter % e % boost::this_thread::get_id();
2453                         putLogDebug(600079, formatter.str(), __FILE__, __LINE__);
2454                 }
2455                 /*------DEBUG LOG END------*/
2456
2457                 //set return status
2458                 status = FINALIZE;
2459         } catch (const std::exception &ex) {
2460                 std::cerr << "protocol_module_ip::handle_realserver_connection_fail() : exception : error = " << ex.what() << "." << std::endl;
2461                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2462                                         "handle_realserver_connection_fail() : exception : error = %s. thread id : %d.");
2463                 formatter % ex.what() % boost::this_thread::get_id();
2464                 putLogError(600049, formatter.str(), __FILE__, __LINE__);
2465
2466                 //set return status
2467                 status = FINALIZE;
2468         } catch (...) {
2469                 std::cerr << "protocol_module_ip::handle_realserver_connection_fail() : Unknown exception." << std::endl;
2470                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
2471                                         "protocol_module_ip::handle_realserver_connection_fail() : "
2472                                         "Unknown exception. thread id : %d.");
2473                 formatter % boost::this_thread::get_id();
2474                 putLogError(600050, formatter.str(), __FILE__, __LINE__);
2475
2476                 //set return status
2477                 status = FINALIZE;
2478         }
2479
2480         /*-------- DEBUG LOG --------*/
2481         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2482                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2483                                         "handle_realserver_connection_fail(const boost::thread::id thread_id, "
2484                                         "const boost::asio::ip::tcp::endpoint& rs_endpoint) : return_value = %d. thread id : %d.");
2485                 formatter % status % boost::this_thread::get_id();
2486                 putLogDebug(600080, formatter.str(), __FILE__, __LINE__);
2487         }
2488         /*------DEBUG LOG END------*/
2489
2490         return status;
2491 }
2492 //! called from after realserver send.
2493 //! @param[in]    upstream thread id
2494 //! @return        session use EVENT mode.
2495 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_send(
2496         const boost::thread::id thread_id)
2497 {
2498         /*-------- DEBUG LOG --------*/
2499         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2500                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2501                                         "handle_realserver_send(const boost::thread::id thread_id) : thread_id = %d.");
2502                 formatter % thread_id;
2503                 putLogDebug(600081, formatter.str(), __FILE__, __LINE__);
2504         }
2505         /*------DEBUG LOG END------*/
2506
2507         EVENT_TAG status                = FINALIZE;
2508         size_t http_header_all_offset            = 0;
2509         size_t http_header_all_len            = 0;
2510         size_t http_header_content_length_offset    = 0;
2511         size_t http_header_content_length_len        = 0;
2512         const size_t CR_LF_LEN                = 2;
2513         const size_t CR_LF_CR_LF_LEN            = 4;
2514         int content_length_value            = 0;
2515
2516         std::string content_length;
2517         cmatch regex_ret;
2518         cregex content_length_regex = icase("Content-Length") >> ":" >> *~_d >> (s1 = +_d) >> *~_d;
2519
2520
2521         bool find_ret = false;
2522         http_utility::CHECK_RESULT_TAG check_ret;
2523
2524         thread_data_ptr session_data_ptr;
2525         session_thread_data_map_it session_thread_it;
2526
2527         try {
2528                 {
2529                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
2530
2531                         //thread id check
2532                         session_thread_it = session_thread_data_map.find(thread_id);
2533                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
2534                                 boost::format formatter("Invalid thread id. thread id : %d.");
2535                                 formatter % boost::this_thread::get_id();
2536                                 putLogError(600051, formatter.str(), __FILE__, __LINE__);
2537                                 throw - 1;
2538                         }
2539
2540                         session_data_ptr = session_thread_it->second;
2541                 }
2542
2543                 //current_message_rest_size > 0
2544                 if (session_data_ptr->current_message_rest_size > 0) {
2545                         //data size > 0
2546                         if (session_data_ptr->data_length > 0) {
2547                                 //set return status
2548                                 status = REALSERVER_CONNECT;
2549                         }
2550                         //data size is 0
2551                         else {
2552                                 //data offset is 0
2553                                 session_data_ptr->data_offset = 0;
2554
2555                                 //set return status
2556                                 status = CLIENT_RECV;
2557                         }
2558                 }
2559                 //current_message_rest_size is 0
2560                 else {
2561                         //data size > 0
2562                         if (session_data_ptr->data_length > 0) {
2563                                 //data state is HTTP_BODY
2564                                 if (session_data_ptr->data_state == HTTP_BODY) {
2565                                         //search whole http header, get whole http header's offset and length
2566                                         find_ret = http_utility::find_http_header_all(session_data_ptr->data_buffer + session_data_ptr->data_offset,
2567                                                         session_data_ptr->data_length,
2568                                                         http_header_all_offset,
2569                                                         http_header_all_len
2570                                                                                      );
2571
2572                                         /*-------- DEBUG LOG --------*/
2573                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2574                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2575                                                                         "handle_realserver_send() : call find_http_header_all : "
2576                                                                         "return_value = %d. thread id : %d.");
2577                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
2578                                                 putLogDebug(600082, formatter.str(), __FILE__, __LINE__);
2579                                         }
2580                                         /*------DEBUG LOG END------*/
2581
2582                                         //search http header result is NG
2583                                         if (!find_ret) {
2584                                                 //set data state HTTP_START
2585                                                 session_data_ptr->data_state = HTTP_START;
2586
2587                                                 //set return status
2588                                                 status = CLIENT_RECV;
2589                                         }
2590                                         //search http header result is OK
2591                                         else {
2592                                                 //check http method and version
2593                                                 check_ret = http_utility::check_http_method_and_version(session_data_ptr->data_buffer + session_data_ptr->data_offset,
2594                                                                 session_data_ptr->data_length);
2595
2596                                                 /*-------- DEBUG LOG --------*/
2597                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2598                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2599                                                                                 "handle_realserver_send() : call check_http_method_and_version : "
2600                                                                                 "return_value = %d. thread id : %d.");
2601                                                         formatter % check_ret % boost::this_thread::get_id();
2602                                                         putLogDebug(600083, formatter.str(), __FILE__, __LINE__);
2603                                                 }
2604                                                 /*------DEBUG LOG END------*/
2605
2606                                                 //check method and version result is NG
2607                                                 if (check_ret == http_utility::CHECK_NG) {
2608                                                         //set current message rest size
2609                                                         session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
2610
2611                                                         //set data state UNKNOWN
2612                                                         session_data_ptr->data_state = UNKNOWN;
2613                                                 }
2614                                                 //check method and version result is OK
2615                                                 else {
2616                                                         //search Content_Length header
2617                                                         find_ret = http_utility::find_http_header_content_length(session_data_ptr->data_buffer + session_data_ptr->data_offset,
2618                                                                         session_data_ptr->data_length,
2619                                                                         http_header_content_length_offset,
2620                                                                         http_header_content_length_len);
2621
2622                                                         /*-------- DEBUG LOG --------*/
2623                                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2624                                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2625                                                                                         "handle_realserver_send() : call find_http_header_content_length : "
2626                                                                                         "return_value = %d. thread id : %d.");
2627                                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
2628                                                                 putLogDebug(600084, formatter.str(), __FILE__, __LINE__);
2629                                                         }
2630                                                         /*------DEBUG LOG END------*/
2631
2632                                                         //search Content_Length result is OK
2633                                                         if (find_ret) {
2634                                                                 content_length.assign(session_data_ptr->data_buffer + session_data_ptr->data_offset + http_header_content_length_offset,
2635                                                                                       http_header_content_length_len);
2636                                                                 find_ret = regex_search(content_length.c_str(), regex_ret, content_length_regex);
2637
2638                                                                 //"content-length: ddd\r\n"
2639                                                                 if (find_ret) {
2640                                                                         content_length = content_length.substr(
2641                                                                                                  regex_ret.position(1),
2642                                                                                                  regex_ret.length(1));
2643
2644                                                                         //set content length value
2645                                                                         content_length_value = boost::lexical_cast<int>(content_length);
2646                                                                 }
2647
2648                                                                 //http_header context is "\r\n\r\n" only
2649                                                                 if (http_header_all_len == 0) {
2650                                                                         //set current message rest size
2651                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + content_length_value + CR_LF_LEN;
2652                                                                 } else {
2653                                                                         //set current message rest size
2654                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + content_length_value + CR_LF_CR_LF_LEN;
2655                                                                 }
2656                                                         }
2657                                                         //search Content_Length result is OK
2658                                                         else {
2659                                                                 //http_header context is "\r\n\r\n" only
2660                                                                 if (http_header_all_len == 0) {
2661                                                                         //set current message rest size
2662                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + CR_LF_LEN;
2663                                                                 } else {
2664                                                                         //set current message rest size
2665                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + CR_LF_CR_LF_LEN;
2666                                                                 }
2667
2668                                                         }
2669
2670                                                         //increment http statistics
2671                                                         increment_stats(session_data_ptr->data_buffer + session_data_ptr->data_offset);
2672                                                         /*-------- DEBUG LOG --------*/
2673                                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2674                                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2675                                                                                         "handle_realserver_send() : call increment_stats : thread id : %d.");
2676                                                                 formatter % boost::this_thread::get_id();
2677                                                                 putLogDebug(600229, formatter.str(), __FILE__, __LINE__);
2678                                                         }
2679                                                         /*------DEBUG LOG END------*/
2680
2681                                                         //set data state HTTP_HEADER
2682                                                         session_data_ptr->data_state = HTTP_HEADER;
2683                                                 }
2684
2685                                                 //set return status
2686                                                 status = REALSERVER_CONNECT;
2687                                         }
2688                                 }
2689                                 //data state is UNKNOWN
2690                                 else if (session_data_ptr->data_state == UNKNOWN) {
2691                                         //set return status
2692                                         status = REALSERVER_CONNECT;
2693                                 }
2694
2695                         }
2696                         //data size is 0
2697                         else {
2698                                 //data state is HTTP_BODY
2699                                 if (session_data_ptr->data_state == HTTP_BODY) {
2700                                         //set data state HTTP_START
2701                                         session_data_ptr->data_state = HTTP_START;
2702                                 }
2703
2704                                 //set data offset 0
2705                                 session_data_ptr->data_offset = 0;
2706
2707                                 //set return status
2708                                 status = CLIENT_RECV;
2709                         }
2710                 }
2711                 //set last status
2712                 session_data_ptr->last_status = status;
2713         } catch (int e) {
2714                 /*-------- DEBUG LOG --------*/
2715                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2716                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2717                                                 "handle_realserver_send() : catch exception e = %d. thread id : %d.");
2718                         formatter % e % boost::this_thread::get_id();
2719                         putLogDebug(600085, formatter.str(), __FILE__, __LINE__);
2720                 }
2721                 /*------DEBUG LOG END------*/
2722
2723                 //set return status
2724                 status = FINALIZE;
2725         } catch (const boost::bad_lexical_cast &) {
2726                 std::cerr << "protocol_module_ip::handle_realserver_send() : exception : " <<  "Content_Length field's value is invalid." << std::endl;
2727                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_send() : "
2728                                         "Content_Length field's value is invalid. thread id : %d.");
2729                 formatter % boost::this_thread::get_id();
2730                 putLogError(600052, formatter.str(), __FILE__, __LINE__);
2731
2732                 //set return status
2733                 status = FINALIZE;
2734         } catch (const std::exception &ex) {
2735                 std::cerr << "protocol_module_ip::handle_realserver_send() : exception : error = " << ex.what() << "." << std::endl;                //set data state HTTP_HEADER
2736                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2737                                         "handle_realserver_send() : exception : error = %s. thread id : %d.");
2738                 formatter % ex.what() % boost::this_thread::get_id();
2739                 putLogError(600053, formatter.str(), __FILE__, __LINE__);
2740
2741                 //set return status
2742                 status = FINALIZE;
2743         } catch (...) {
2744                 std::cerr << "protocol_module_ip::handle_realserver_send() : Unknown exception." << std::endl;
2745                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
2746                                         "protocol_module_ip::handle_realserver_send() : "
2747                                         "Unknown exception. thread id : %d.");
2748                 formatter % boost::this_thread::get_id();
2749                 putLogError(600054, formatter.str(), __FILE__, __LINE__);
2750
2751                 //set return status
2752                 status = FINALIZE;
2753         }
2754
2755         /*-------- DEBUG LOG --------*/
2756         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2757                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2758                                         "handle_realserver_send(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
2759                 formatter % status % boost::this_thread::get_id();
2760                 putLogDebug(600086, formatter.str(), __FILE__, __LINE__);
2761         }
2762         /*------DEBUG LOG END------*/
2763
2764         return status;
2765 }
2766
2767 //! called from after sorryserver select
2768 //! @param[in]    upstream thread id
2769 //! @param[in]    sorryserver endpoint reference
2770 //! @return        session use EVENT mode.
2771 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_select(
2772         const boost::thread::id thread_id, boost::asio::ip::tcp::endpoint &sorry_endpoint)
2773 {
2774         /*-------- DEBUG LOG --------*/
2775         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2776                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2777                                         "handle_sorryserver_select(const boost::thread::id thread_id, "
2778                                         "boost::asio::ip::tcp::endpoint& sorry_endpoint) : "
2779                                         "thread_id = %d, sorry_endpoint = [%s]:%d.");
2780                 formatter % thread_id % sorry_endpoint.address().to_string() % sorry_endpoint.port();
2781                 putLogDebug(600087, formatter.str(), __FILE__, __LINE__);
2782         }
2783         /*------DEBUG LOG END------*/
2784
2785         EVENT_TAG status = FINALIZE;
2786         boost::asio::ip::tcp::endpoint tmp_endpoint;
2787         thread_data_ptr session_data_ptr;
2788         session_thread_data_map_it session_thread_it;
2789         session_thread_data_map_it session_thread_it_end;
2790
2791         try {
2792                 {
2793                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
2794
2795                         session_thread_it = session_thread_data_map.find(thread_id);
2796                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
2797                                 boost::format formatter("Invalid thread id. thread id : %d.");
2798                                 formatter % boost::this_thread::get_id();
2799                                 putLogError(600055, formatter.str(), __FILE__, __LINE__);
2800                                 throw - 1;
2801                         }
2802
2803                         session_data_ptr = session_thread_it->second;
2804                 }
2805
2806                 //data state is HTTP_START
2807                 if (session_data_ptr->data_state == HTTP_START) {
2808                         //set return status
2809                         status = CLIENT_RECV;
2810                 }
2811                 //data state is not HTTP_START
2812                 else {
2813                         //set return status
2814                         status = SORRYSERVER_CONNECT;
2815                 }
2816
2817                 //set last status
2818                 session_data_ptr->last_status = status;
2819         } catch (int e) {
2820                 /*-------- DEBUG LOG --------*/
2821                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2822                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2823                                                 "handle_sorryserver_select() : catch exception e = %d. thread id : %d.");
2824                         formatter % e % boost::this_thread::get_id();
2825                         putLogDebug(600088, formatter.str(), __FILE__, __LINE__);
2826                 }
2827                 /*------DEBUG LOG END------*/
2828
2829                 //set return status
2830                 status = FINALIZE;
2831         } catch (const std::exception &ex) {
2832                 std::cerr << "protocol_module_ip::handle_sorryserver_select() : exception : error = " << ex.what() << "." << std::endl;
2833                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2834                                         "handle_sorryserver_select() : exception : error = %s. thread id : %d.");
2835                 formatter % ex.what() % boost::this_thread::get_id();
2836                 putLogError(600056, formatter.str(), __FILE__, __LINE__);
2837
2838                 //set return status
2839                 status = FINALIZE;
2840         } catch (...) {
2841                 std::cerr << "protocol_module_ip::handle_sorryserver_select() : Unknown exception." << std::endl;
2842                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
2843                                         "protocol_module_ip::handle_sorryserver_select() : "
2844                                         "Unknown exception. thread id : %d.");
2845                 formatter % boost::this_thread::get_id();
2846                 putLogError(600057, formatter.str(), __FILE__, __LINE__);
2847
2848                 //set return status
2849                 status = FINALIZE;
2850         }
2851
2852         /*-------- DEBUG LOG --------*/
2853         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2854                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2855                                         "handle_sorryserver_select(const boost::thread::id thread_id, "
2856                                         "boost::asio::ip::tcp::endpoint& sorry_endpoint)"
2857                                         " : return_value = %d. thread id : %d.");
2858                 formatter % status % boost::this_thread::get_id();
2859                 putLogDebug(600089, formatter.str(), __FILE__, __LINE__);
2860         }
2861         /*------DEBUG LOG END------*/
2862
2863         return status;
2864 }
2865
2866 //! called from after sorryserver connect
2867 //!    @param[in]    upstream thread id
2868 //! @param[out]    send buffer reference.
2869 //! @param[out]    send length
2870 //! @return        session use EVENT mode.
2871 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_connect(
2872         const boost::thread::id thread_id, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen)
2873 {
2874         /*-------- DEBUG LOG --------*/
2875         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2876                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2877                                         "handle_sorryserver_connect(const boost::thread::id thread_id, "
2878                                         "boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t& datalen) : "
2879                                         "thread_id = %d.");
2880                 formatter % thread_id;
2881                 putLogDebug(600090, formatter.str(), __FILE__, __LINE__);
2882         }
2883         /*------DEBUG LOG END------*/
2884
2885         EVENT_TAG status            = FINALIZE;
2886         size_t send_possible_size        = 0;
2887         size_t uri_offset            = 0;
2888         size_t uri_len                = 0;
2889         size_t x_forwarded_for_insert_pos   = 0;
2890         thread_data_ptr                session_data_ptr;
2891         session_thread_data_map_it        session_thread_it;
2892         std::pair<char *, size_t>        buffer_element;
2893         std::string                x_forwarded_for_context;
2894
2895         try {
2896                 {
2897                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
2898
2899                         //thread id check
2900                         session_thread_it = session_thread_data_map.find(thread_id);
2901                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
2902                                 boost::format formatter("Invalid thread id. thread id : %d.");
2903                                 formatter % boost::this_thread::get_id();
2904                                 putLogError(600058, formatter.str(), __FILE__, __LINE__);
2905                                 throw - 1;
2906                         }
2907
2908                         session_data_ptr = session_thread_it->second;
2909                 }
2910                 //set send possible data size
2911                 send_possible_size = std::min(session_data_ptr->current_message_rest_size,
2912                                               session_data_ptr->data_length
2913                                              );
2914
2915                 if (session_data_ptr->buffer_sequence.empty()) {
2916                         //data state is HTTP_HEADER
2917                         if (session_data_ptr->data_state == HTTP_HEADER) {
2918                                 //search uri
2919                                 http_utility::find_uri(session_data_ptr->data_buffer + session_data_ptr->data_offset,
2920                                                        session_data_ptr->data_length, uri_offset, uri_len);
2921
2922                                 //set buffer's position
2923                                 buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset;
2924                                 buffer_element.second = uri_offset;
2925
2926                                 //put buffer data to buffer_sequence
2927                                 session_data_ptr->buffer_sequence.push_back(buffer_element);
2928
2929                                 //set buffer's position
2930                                 buffer_element.first = sorry_uri.data();
2931                                 buffer_element.second = strlen(sorry_uri.data());
2932
2933                                 //put buffer data to buffer_sequence
2934                                 session_data_ptr->buffer_sequence.push_back(buffer_element);
2935
2936                                 //forwarded_for flag is on
2937                                 if (forwarded_for == FORWARDED_FOR_ON) {
2938                                         create_x_forwarded_for(session_data_ptr->client_endpoint.address().to_string(),
2939                                                                session_data_ptr->data_buffer + session_data_ptr->data_offset,
2940                                                                session_data_ptr->data_length,
2941                                                                x_forwarded_for_insert_pos,
2942                                                                x_forwarded_for_context);
2943
2944                                         //set buffer's position
2945                                         buffer_element.first = session_data_ptr->data_buffer
2946                                                                + session_data_ptr->data_offset
2947                                                                + uri_offset
2948                                                                + uri_len;
2949                                         buffer_element.second = x_forwarded_for_insert_pos - uri_offset - uri_len;
2950
2951                                         //put buffer data to buffer_sequence
2952                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2953
2954                                         session_data_ptr->forwarded_for_buffer.assign(0);
2955
2956                                         /*-------- DEBUG LOG --------*/
2957                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2958                                                 std::string datadump;
2959                                                 dump_memory(x_forwarded_for_context.c_str(),
2960                                                             x_forwarded_for_context.size(), datadump);
2961                                                 boost::format formatter(
2962                                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2963                                                         "handle_sorryserver_connect() : before memcpy (data dump) : "
2964                                                         "data begin = 0, data_size = %d, data = %s");
2965                                                 formatter %  x_forwarded_for_context.size() % datadump;
2966                                                 putLogDebug(600091, formatter.str(), __FILE__, __LINE__);
2967                                         }
2968                                         /*------DEBUG LOG END------*/
2969
2970                                         memcpy(session_data_ptr->forwarded_for_buffer.data(),
2971                                                x_forwarded_for_context.c_str(),
2972                                                x_forwarded_for_context.size());
2973
2974                                         /*-------- DEBUG LOG --------*/
2975                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2976                                                 std::string datadump;
2977                                                 dump_memory(x_forwarded_for_context.c_str(),
2978                                                             x_forwarded_for_context.size(), datadump);
2979                                                 boost::format formatter(
2980                                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2981                                                         "handle_sorryserver_connect() : after memcpy (data dump) : "
2982                                                         "data begin = 0, data_size = %d, data = %s");
2983                                                 formatter % x_forwarded_for_context.size() % datadump;
2984                                                 putLogDebug(600092, formatter.str(), __FILE__, __LINE__);
2985                                         }
2986                                         /*------DEBUG LOG END------*/
2987
2988                                         //set buffer's position
2989                                         buffer_element.first = session_data_ptr->forwarded_for_buffer.data();
2990                                         buffer_element.second = x_forwarded_for_context.size();
2991                                         //put buffer data to buffer_sequence
2992                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2993
2994                                         //set buffer's position
2995                                         buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset + x_forwarded_for_insert_pos;
2996                                         buffer_element.second = send_possible_size - x_forwarded_for_insert_pos;
2997                                         //put buffer data to buffer_sequence
2998                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2999                                 }
3000                                 //forwarded_for flag is on
3001                                 else {
3002                                         //set buffer's position
3003                                         buffer_element.first = session_data_ptr->data_buffer
3004                                                                + session_data_ptr->data_offset
3005                                                                + uri_offset
3006                                                                + uri_len;
3007                                         buffer_element.second = send_possible_size - uri_offset - uri_len;
3008                                         //put buffer data to buffer_sequence
3009                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
3010                                 }
3011
3012                                 //set data state HTTP_BODY
3013                                 session_data_ptr->data_state = HTTP_BODY;
3014                         }
3015                         //data state is not HTTP_HEADER
3016                         else {
3017                                 //set buffer's position
3018                                 buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset;
3019                                 buffer_element.second = send_possible_size;
3020                                 //put buffer data to buffer_sequence
3021                                 session_data_ptr->buffer_sequence.push_back(buffer_element);
3022                         }
3023                 }
3024
3025                 //put buffer_sequence data into sendbuffer
3026                 put_data_into_sendbuffer(session_data_ptr, sendbuffer, datalen);
3027
3028                 //set return status
3029                 status = SORRYSERVER_SEND;
3030
3031                 //set last status
3032                 session_data_ptr->last_status = status;
3033
3034         } catch (int e) {
3035                 /*-------- DEBUG LOG --------*/
3036                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3037                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3038                                                 "handle_sorryserver_connect() : catch exception e = %d. thread id : %d.");
3039                         formatter % e % boost::this_thread::get_id();
3040                         putLogDebug(600093, formatter.str(), __FILE__, __LINE__);
3041                 }
3042                 /*------DEBUG LOG END------*/
3043
3044                 //set return status
3045                 status = FINALIZE;
3046         } catch (const std::exception &ex) {
3047                 std::cerr << "protocol_module_ip::handle_sorryserver_connect() : exception : error = " << ex.what() << "." << std::endl;
3048                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3049                                         "handle_sorryserver_connect() : exception : error = %s. thread id : %d.");
3050                 formatter % ex.what() % boost::this_thread::get_id();
3051                 putLogError(600059, formatter.str(), __FILE__, __LINE__);
3052
3053                 //set return status
3054                 status = FINALIZE;
3055         } catch (...) {
3056                 std::cerr << "protocol_module_ip::handle_sorryserver_connect() : Unknown exception." << std::endl;
3057                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3058                                         "handle_sorryserver_connect() : Unknown exception. thread id : %d.");
3059                 formatter % boost::this_thread::get_id();
3060                 putLogError(600060, formatter.str(), __FILE__, __LINE__);
3061
3062                 //set return status
3063                 status = FINALIZE;
3064         }
3065
3066         /*-------- DEBUG LOG --------*/
3067         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3068                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3069                                         "handle_sorryserver_connect(const boost::thread::id thread_id, "
3070                                         "boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
3071                                         "size_t& datalen) : return_value = %d. thread id : %d.");
3072                 formatter % status % boost::this_thread::get_id();
3073                 putLogDebug(600094, formatter.str(), __FILE__, __LINE__);
3074         }
3075         /*------DEBUG LOG END------*/
3076
3077         return status;
3078 }
3079 //! called from after sorryserver connection fail
3080 //! @param[in]    upstream thread id
3081 //! @param[in]    sorryserver endpoint reference.
3082 //! @return        session use EVENT mode.
3083 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_connection_fail(
3084         const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &sorry_endpoint)
3085 {
3086         /*-------- DEBUG LOG --------*/
3087         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3088                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3089                                         "handle_sorryserver_connection_fail(const boost::thread::id thread_id, "
3090                                         "const boost::asio::ip::tcp::endpoint& sorry_endpoint) : "
3091                                         "thread_id = %d, sorry_endpoint = [%s]:%d.");
3092                 formatter % thread_id % sorry_endpoint.address().to_string() % sorry_endpoint.port();
3093                 putLogDebug(600095, formatter.str(), __FILE__, __LINE__);
3094         }
3095         /*------DEBUG LOG END------*/
3096
3097         EVENT_TAG status = FINALIZE;
3098         thread_data_ptr session_data_ptr;
3099         session_thread_data_map_it session_thread_it;
3100
3101         try {
3102                 boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
3103
3104                 session_thread_it = session_thread_data_map.find(thread_id);
3105                 if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
3106                         boost::format formatter("Invalid thread id. thread id : %d.");
3107                         formatter % boost::this_thread::get_id();
3108                         putLogError(600061, formatter.str(), __FILE__, __LINE__);
3109                         throw - 1;
3110                 }
3111
3112                 session_data_ptr = session_thread_it->second;
3113
3114                 //set return status
3115                 status = FINALIZE;
3116
3117                 //set last status
3118                 session_data_ptr->last_status = status;
3119         } catch (int e) {
3120                 /*-------- DEBUG LOG --------*/
3121                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3122                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3123                                                 "handle_sorryserver_connection_fail() : catch exception e = %d. thread id : %d.");
3124                         formatter % e % boost::this_thread::get_id();
3125                         putLogDebug(600096, formatter.str(), __FILE__, __LINE__);
3126                 }
3127                 /*------DEBUG LOG END------*/
3128
3129                 //set return status
3130                 status = FINALIZE;
3131         } catch (const std::exception &ex) {
3132                 std::cerr << "protocol_module_ip::handle_sorryserver_connection_fail() : exception : error = " << ex.what() << "." << std::endl;
3133                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3134                                         "handle_sorryserver_connection_fail() : exception : error = %s. thread id : %d.");
3135                 formatter % ex.what() % boost::this_thread::get_id();
3136                 putLogError(600062, formatter.str(), __FILE__, __LINE__);
3137
3138                 //set return status
3139                 status = FINALIZE;
3140         } catch (...) {
3141                 std::cerr << "protocol_module_ip::handle_sorryserver_connection_fail() : Unknown exception." << std::endl;
3142                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
3143                                         "protocol_module_ip::handle_sorryserver_connection_fail() : "
3144                                         "Unknown exception. thread id : %d.");
3145                 formatter % boost::this_thread::get_id();
3146                 putLogError(600063, formatter.str(), __FILE__, __LINE__);
3147
3148                 //set return status
3149                 status = FINALIZE;
3150         }
3151
3152         /*-------- DEBUG LOG --------*/
3153         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3154                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3155                                         "handle_sorryserver_connection_fail(const boost::thread::id thread_id, "
3156                                         "const boost::asio::ip::tcp::endpoint& sorry_endpoint) : return_value = %d. thread id : %d.");
3157                 formatter % status % boost::this_thread::get_id();
3158                 putLogDebug(600097, formatter.str(), __FILE__, __LINE__);
3159         }
3160         /*------DEBUG LOG END------*/
3161
3162         return status;
3163 }
3164
3165 //! called from after sorryserver send
3166 //! @param[in]    upstream thread id
3167 //! @return        session use EVENT mode.
3168 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_send(
3169         const boost::thread::id thread_id)
3170 {
3171         /*-------- DEBUG LOG --------*/
3172         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3173                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3174                                         "handle_sorryserver_send(const boost::thread::id thread_id) : thread_id = %d.");
3175                 formatter % thread_id;
3176                 putLogDebug(600098, formatter.str(), __FILE__, __LINE__);
3177         }
3178         /*------DEBUG LOG END------*/
3179
3180         EVENT_TAG status                = FINALIZE;
3181         size_t http_header_all_offset            = 0;
3182         size_t http_header_all_len            = 0;
3183         size_t http_header_content_length_offset    = 0;
3184         size_t http_header_content_length_len        = 0;
3185         const size_t CR_LF_LEN                = 2;
3186         const size_t CR_LF_CR_LF_LEN            = 4;
3187         int content_length_value            = 0;
3188
3189         std::string content_length;
3190         cmatch regex_ret;
3191         cregex content_length_regex = icase("Content-Length") >> ":" >> *~_d >> (s1 = +_d) >> *~_d;
3192
3193
3194         bool find_ret = false;
3195         http_utility::CHECK_RESULT_TAG check_ret;
3196
3197         thread_data_ptr session_data_ptr;
3198         session_thread_data_map_it session_thread_it;
3199
3200         try {
3201                 {
3202                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
3203
3204                         //thread id check
3205                         session_thread_it = session_thread_data_map.find(thread_id);
3206                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
3207                                 boost::format formatter("Invalid thread id. thread id : %d.");
3208                                 formatter % boost::this_thread::get_id();
3209                                 putLogError(600064, formatter.str(), __FILE__, __LINE__);
3210                                 throw - 1;
3211                         }
3212
3213                         session_data_ptr = session_thread_it->second;
3214                 }
3215
3216                 //current_message_rest_size > 0
3217                 if (session_data_ptr->current_message_rest_size > 0) {
3218                         //data size > 0
3219                         if (session_data_ptr->data_length > 0) {
3220                                 //set return status
3221                                 status = SORRYSERVER_CONNECT;
3222                         }
3223                         //data size is 0
3224                         else {
3225                                 //data offset is 0
3226                                 session_data_ptr->data_offset = 0;
3227
3228                                 //set return status
3229                                 status =  CLIENT_RECV;
3230                         }
3231                 }
3232                 //current_message_rest_size is 0
3233                 else {
3234                         //data size > 0
3235                         if (session_data_ptr->data_length > 0) {
3236                                 //data state is HTTP_BODY
3237                                 if (session_data_ptr->data_state == HTTP_BODY) {
3238                                         //search whole http header, get whole http header's offset and length
3239                                         find_ret = http_utility::find_http_header_all(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3240                                                         session_data_ptr->data_length,
3241                                                         http_header_all_offset,
3242                                                         http_header_all_len
3243                                                                                      );
3244
3245                                         /*-------- DEBUG LOG --------*/
3246                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3247                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3248                                                                         "handle_sorryserver_send() : call find_http_header_all : "
3249                                                                         "return_value = %d. thread id : %d.");
3250                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
3251                                                 putLogDebug(600099, formatter.str(), __FILE__, __LINE__);
3252                                         }
3253                                         /*------DEBUG LOG END------*/
3254
3255                                         //search http header result is NG
3256                                         if (!find_ret) {
3257                                                 //set data state HTTP_START
3258                                                 session_data_ptr->data_state = HTTP_START;
3259
3260                                                 //set return status
3261                                                 status = CLIENT_RECV;
3262                                         }
3263                                         //check method and version result is OK
3264                                         else {
3265                                                 //search Content_Length header
3266                                                 check_ret = http_utility::check_http_method_and_version(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3267                                                                 session_data_ptr->data_length);
3268
3269                                                 /*-------- DEBUG LOG --------*/
3270                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3271                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3272                                                                                 "handle_sorryserver_send() : call check_http_method_and_version : "
3273                                                                                 "return_value = %d. thread id : %d.");
3274                                                         formatter % check_ret % boost::this_thread::get_id();
3275                                                         putLogDebug(600100, formatter.str(), __FILE__, __LINE__);
3276                                                 }
3277                                                 /*------DEBUG LOG END------*/
3278
3279                                                 //check method and version result is NG
3280                                                 if (check_ret == http_utility::CHECK_NG) {
3281                                                         //set current message rest size
3282                                                         session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3283
3284                                                         //set data state UNKNOWN
3285                                                         session_data_ptr->data_state = UNKNOWN;
3286                                                 }
3287                                                 //check method and version result is OK
3288                                                 else {
3289                                                         //search Content_Length header
3290                                                         find_ret = http_utility::find_http_header_content_length(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3291                                                                         session_data_ptr->data_length,
3292                                                                         http_header_content_length_offset,
3293                                                                         http_header_content_length_len);
3294
3295                                                         /*-------- DEBUG LOG --------*/
3296                                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3297                                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3298                                                                                         "handle_sorryserver_send() : call find_http_header_content_length : "
3299                                                                                         "return_value = %d. thread id : %d.");
3300                                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
3301                                                                 putLogDebug(600101, formatter.str(), __FILE__, __LINE__);
3302                                                         }
3303                                                         /*------DEBUG LOG END------*/
3304
3305                                                         //search Content_Length result is OK
3306                                                         if (find_ret) {
3307                                                                 content_length.assign(session_data_ptr->data_buffer + session_data_ptr->data_offset + http_header_content_length_offset,
3308                                                                                       http_header_content_length_len);
3309                                                                 find_ret = regex_search(content_length.c_str(), regex_ret, content_length_regex);
3310
3311                                                                 //"content-length: ddd\r\n"
3312                                                                 if (find_ret) {
3313                                                                         content_length = content_length.substr(
3314                                                                                                  regex_ret.position(1),
3315                                                                                                  regex_ret.length(1));
3316
3317                                                                         //set content length value
3318                                                                         content_length_value = boost::lexical_cast<int>(content_length);
3319                                                                 }
3320
3321                                                                 //http_header context is "\r\n\r\n" only
3322                                                                 if (http_header_all_len == 0) {
3323                                                                         //set current message rest size
3324                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + content_length_value + CR_LF_LEN;
3325                                                                 } else {
3326                                                                         //set current message rest size
3327                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + content_length_value + CR_LF_CR_LF_LEN;
3328                                                                 }
3329                                                         }
3330                                                         //search Content_Length result is OK
3331                                                         else {
3332                                                                 //http_header context is "\r\n\r\n" only
3333                                                                 if (http_header_all_len == 0) {
3334                                                                         //set current message rest size
3335                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + CR_LF_LEN;
3336                                                                 } else {
3337                                                                         //set current message rest size
3338                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + CR_LF_CR_LF_LEN;
3339                                                                 }
3340
3341                                                         }
3342
3343                                                         //set data state HTTP_HEADER
3344                                                         session_data_ptr->data_state = HTTP_HEADER;
3345
3346                                                 }
3347                                                 //set return status
3348                                                 status = SORRYSERVER_CONNECT;
3349                                         }
3350                                 }
3351                                 //data state is UNKNOWN
3352                                 else if (session_data_ptr->data_state == UNKNOWN) {
3353                                         //set return status
3354                                         status = SORRYSERVER_CONNECT;
3355                                 }
3356
3357                         }
3358                         //data size is 0
3359                         else {
3360                                 //data state is HTTP_BODY
3361                                 if (session_data_ptr->data_state == HTTP_BODY) {
3362                                         //set data state HTTP_START
3363                                         session_data_ptr->data_state = HTTP_START;
3364                                 }
3365
3366                                 //set data offset 0
3367                                 session_data_ptr->data_offset = 0;
3368
3369                                 //set return status
3370                                 status = CLIENT_RECV;
3371                         }
3372                 }
3373
3374                 //set last status
3375                 session_data_ptr->last_status = status;
3376         } catch (int e) {
3377                 /*-------- DEBUG LOG --------*/
3378                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3379                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3380                                                 "handle_sorryserver_send() : catch exception e = %d. thread id : %d.");
3381                         formatter % e % boost::this_thread::get_id();
3382                         putLogDebug(600102, formatter.str(), __FILE__, __LINE__);
3383                 }
3384                 /*------DEBUG LOG END------*/
3385
3386                 //set return status
3387                 status = FINALIZE;
3388         } catch (const boost::bad_lexical_cast &) {
3389                 std::cerr << "protocol_module_ip::handle_sorryserver_send() : exception : " <<  "Content_Length field's value is invalid." << std::endl;
3390                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_send() : "
3391                                         "Content_Length field's value is invalid. thread id : %d.");
3392                 formatter % boost::this_thread::get_id();
3393                 putLogError(600065, formatter.str(), __FILE__, __LINE__);
3394
3395                 //set return status
3396                 status = FINALIZE;
3397         } catch (const std::exception &ex) {
3398                 std::cerr << "protocol_module_ip::handle_sorryserver_send() : exception : error = " << ex.what() << "." << std::endl;
3399                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3400                                         "handle_sorryserver_send() : exception : error = %s. thread id : %d.");
3401                 formatter % ex.what() % boost::this_thread::get_id();
3402                 putLogError(600066, formatter.str(), __FILE__, __LINE__);
3403
3404                 //set return status
3405                 status = FINALIZE;
3406         } catch (...) {
3407                 std::cerr << "protocol_module_ip::handle_sorryserver_send() : Unknown exception." << std::endl;
3408                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
3409                                         "protocol_module_ip::handle_sorryserver_send() : "
3410                                         "Unknown exception. thread id : %d.");
3411                 formatter % boost::this_thread::get_id();
3412                 putLogError(600067, formatter.str(), __FILE__, __LINE__);
3413
3414                 //set return status
3415                 status = FINALIZE;
3416         }
3417
3418         /*-------- DEBUG LOG --------*/
3419         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3420                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3421                                         "handle_sorryserver_send(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
3422                 formatter % status % boost::this_thread::get_id();
3423                 putLogDebug(600103, formatter.str(), __FILE__, __LINE__);
3424         }
3425         /*------DEBUG LOG END------*/
3426
3427         return status;
3428 }
3429
3430 //! called from after realserver receive.for UDP
3431 //! @param[in]    downstream thread id
3432 //! @param[in]    realserver UDP endpoint reference
3433 //! @param[in]    receive from realserver buffer reference
3434 //! @param[in]    recv data length
3435 //! @return        session use EVENT mode.
3436 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_recv(
3437         const boost::thread::id thread_id, const boost::asio::ip::udp::endpoint &rs_endpoint, const boost::array < char,
3438         MAX_BUFFER_SIZE > & recvbuffer, const size_t recvlen)
3439 {
3440         /*-------- DEBUG LOG --------*/
3441         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3442                 boost::format formatter("in/out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3443                                         "handle_realserver_recv(const boost::thread::id thread_id, "
3444                                         "const boost::asio::ip::udp::endpoint& rs_endpoint, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3445                                         "const size_t& recvlen) : "
3446                                         "return_value = %d. thread id : %d.");
3447                 formatter % STOP % boost::this_thread::get_id();
3448                 putLogDebug(600104, formatter.str(), __FILE__, __LINE__);
3449         }
3450         /*------DEBUG LOG END------*/
3451         return STOP;
3452 }
3453
3454 //! called from after realserver receive for TCP/IP
3455 //! @param[in]    downstream thread id
3456 //! @param[in]    realserver TCP/IP endpoint reference
3457 //! @param[in]    realserver receive buffer reference.
3458 //! @param[in]    recv data length
3459 //! @return        session use EVENT mode.
3460 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_recv(
3461         const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &rs_endpoint, const boost::array < char,
3462         MAX_BUFFER_SIZE > & recvbuffer, const size_t recvlen)
3463 {
3464         /*-------- DEBUG LOG --------*/
3465         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3466                 size_t buffer_size = recvbuffer.size() < recvlen ? recvbuffer.size() : recvlen;
3467                 std::string buffer;
3468                 dump_memory(recvbuffer.data(), buffer_size, buffer);
3469                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3470                                         "handle_realserver_recv(const boost::thread::id thread_id, "
3471                                         "const boost::asio::ip::tcp::endpoint& rs_endpoint, "
3472                                         "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3473                                         "const size_t recvlen) : thread_id = %d, rs_endpoint = [%s]:%d, recvbuffer = %s, recvlen = %d.");
3474                 formatter % thread_id % rs_endpoint.address().to_string() % rs_endpoint.port()
3475                 % buffer % recvlen;
3476                 putLogDebug(600105, formatter.str(), __FILE__, __LINE__);
3477         }
3478         /*------DEBUG LOG END------*/
3479
3480         EVENT_TAG status                = FINALIZE;
3481
3482         bool find_ret                    = false;
3483         size_t http_header_offset            = 0;
3484         size_t http_header_len                = 0;
3485         size_t http_header_content_length_offset    = 0;
3486         size_t http_header_content_length_len        = 0;
3487         int content_length_value            = 0;
3488         const size_t CR_LF_LEN                = 2; //length of "\r\n"
3489         const size_t CR_LF_CR_LF_LEN            = 4; //length of "\r\n\r\n"
3490
3491         session_thread_data_map_it            session_thread_it;
3492         thread_data_ptr                    session_data_ptr;
3493         http_utility::CHECK_RESULT_TAG            check_ret;
3494
3495         std::string                    content_length;
3496         cmatch                        regex_ret;
3497         cregex content_length_regex = icase("Content-Length") >> ":" >> *~_d >> (s1 = +_d) >> *~_d;
3498
3499         if (unlikely(recvlen > recvbuffer.size())) {
3500                 std::cerr << "protocol_module_ip::handle_realserver_recv() : Data size bigger than buffer size." << std::endl;
3501                 boost::format formatter("Data size bigger than buffer size. thread id : %d.");
3502                 formatter % boost::this_thread::get_id();
3503                 putLogError(600068, formatter.str(), __FILE__, __LINE__);
3504
3505                 /*-------- DEBUG LOG --------*/
3506                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3507                         boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3508                                                 "handle_realserver_recv(const boost::thread::id thread_id, "
3509                                                 "const boost::asio::ip::tcp::endpoint& rs_endpoint, "
3510                                                 "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3511                                                 "const size_t recvlen) : return_value = %d. thread id : %d.");
3512                         formatter % FINALIZE % boost::this_thread::get_id();
3513                         putLogDebug(600106, formatter.str(), __FILE__, __LINE__);
3514                 }
3515                 /*------DEBUG LOG END------*/
3516
3517                 return status;
3518         }
3519
3520         try {
3521                 {
3522                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
3523
3524                         session_thread_it = session_thread_data_map.find(thread_id);
3525                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
3526                                 boost::format formatter("Invalid thread id. thread id : %d.");
3527                                 formatter % boost::this_thread::get_id();
3528                                 putLogError(600069, formatter.str(), __FILE__, __LINE__);
3529                                 throw - 1;
3530                         }
3531
3532                         session_data_ptr = session_thread_it->second;
3533                 }
3534
3535                 //set switch flag off
3536                 session_data_ptr->switch_flag = SWITCH_FLAG_OFF;
3537
3538                 /*-------- DEBUG LOG --------*/
3539                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3540                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3541                                                 "handle_realserver_recv(const boost::thread::id thread_id, "
3542                                                 "const boost::asio::ip::tcp::endpoint& rs_endpoint, "
3543                                                 "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3544                                                 "const size_t recvlen) : SWITCH_FLAG_OFF. "
3545                                                 "thread_id = %d, rs_endpoint = [%s]:%d.");
3546                         formatter % thread_id % rs_endpoint.address().to_string() % rs_endpoint.port();
3547                         putLogDebug(600107, formatter.str(), __FILE__, __LINE__);
3548                 }
3549                 /*------DEBUG LOG END------*/
3550
3551                 //copy data from recvbuffer
3552                 if (!get_data_from_recvbuffer(session_data_ptr, recvbuffer, recvlen)) {
3553                         //copy failed
3554                         std::cerr << "protocol_module_ip::handle_realserver_recv() : Data size bigger than buffer size." << std::endl;
3555                         boost::format formatter("Data size bigger than buffer size. thread id : % id.");
3556                         formatter % boost::this_thread::get_id();
3557                         putLogError(600070, formatter.str(), __FILE__, __LINE__);
3558                         status = FINALIZE;
3559                 } else {
3560                         if (forwarded_for == FORWARDED_FOR_OFF && session_data_ptr->sorry_flag == SORRY_FLAG_OFF) {
3561                                 session_data_ptr->data_state = UNKNOWN;
3562                         }
3563                         //data state is HTTP_START
3564                         if (session_data_ptr->data_state == HTTP_START) {
3565                                 //search http header
3566                                 find_ret = http_utility::find_http_header_all(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3567                                                 session_data_ptr->data_length,
3568                                                 http_header_offset,
3569                                                 http_header_len
3570                                                                              );
3571
3572                                 /*-------- DEBUG LOG --------*/
3573                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3574                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3575                                                                 "handle_realserver_recv() : call find_http_header_all : "
3576                                                                 "return_value = %d. thread id : %d.");
3577                                         formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
3578                                         putLogDebug(600108, formatter.str(), __FILE__, __LINE__);
3579                                 }
3580                                 /*------DEBUG LOG END------*/
3581
3582                                 //search http header result is NG
3583                                 if (!find_ret) {
3584                                         //data size bigger than max buffer size
3585                                         if (session_data_ptr->data_length >= MAX_IP_MODULE_BUFFER_SIZE - recvbuffer.size()) {
3586                                                 //set data state UNKNOWN
3587                                                 session_data_ptr->data_state = UNKNOWN;
3588                                                 //set current message rest size
3589                                                 session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3590                                         }
3591                                 }
3592                                 //search http header result is OK
3593                                 else {
3594                                         //check http version and status code
3595                                         check_ret = http_utility::check_http_version_and_status_code(session_data_ptr->data_buffer,
3596                                                         session_data_ptr->data_length);
3597
3598                                         /*-------- DEBUG LOG --------*/
3599                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3600                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3601                                                                         "handle_realserver_recv() : call check_http_version_and_status_code : "
3602                                                                         "return_value = %d. thread id : %d.");
3603                                                 formatter % check_ret % boost::this_thread::get_id();
3604                                                 putLogDebug(600109, formatter.str(), __FILE__, __LINE__);
3605                                         }
3606                                         /*------DEBUG LOG END------*/
3607
3608                                         //check http version and status code result is NG
3609                                         if (check_ret == http_utility::CHECK_NG) {
3610                                                 //set data state UNKNOWN
3611                                                 session_data_ptr->data_state = UNKNOWN;
3612                                                 //set current message rest size
3613                                                 session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3614                                         }
3615                                         //check http version and status code result is OK
3616                                         else {
3617                                                 //search Content_Length header
3618                                                 find_ret = http_utility::find_http_header_content_length(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3619                                                                 session_data_ptr->data_length,
3620                                                                 http_header_content_length_offset,
3621                                                                 http_header_content_length_len);
3622
3623                                                 /*-------- DEBUG LOG --------*/
3624                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3625                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3626                                                                                 "handle_realserver_recv() : call find_http_header_content_length : "
3627                                                                                 "return_value = %d. thread id : %d.");
3628                                                         formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
3629                                                         putLogDebug(600110, formatter.str(), __FILE__, __LINE__);
3630                                                 }
3631                                                 /*------DEBUG LOG END------*/
3632
3633                                                 //search Content_Length result is OK
3634                                                 if (find_ret) {
3635                                                         //set content length string
3636                                                         content_length.assign(session_data_ptr->data_buffer + session_data_ptr->data_offset + http_header_content_length_offset,
3637                                                                               http_header_content_length_len);
3638                                                         find_ret = regex_search(content_length.c_str(), regex_ret, content_length_regex);
3639
3640                                                         //"content-length: ddd\r\n"
3641                                                         if (find_ret) {
3642                                                                 content_length = content_length.substr(
3643                                                                                          regex_ret.position(1),
3644                                                                                          regex_ret.length(1));
3645
3646                                                                 //set content length value
3647                                                                 content_length_value = boost::lexical_cast<int>(content_length);
3648                                                         }
3649
3650                                                         //http_header context is "\r\n\r\n" only
3651                                                         if (http_header_len == 0) {
3652                                                                 //set current message rest size
3653                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + content_length_value + CR_LF_LEN;
3654                                                         } else {
3655                                                                 //set current message rest size
3656                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + content_length_value + CR_LF_CR_LF_LEN;
3657                                                         }
3658                                                 }
3659                                                 //search Content_Length result is NG
3660                                                 else {
3661                                                         //http_header context is "\r\n\r\n" only
3662                                                         if (http_header_len == 0) {
3663                                                                 //set current message rest size
3664                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + CR_LF_LEN;
3665                                                         } else {
3666                                                                 //set current message rest size
3667                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + CR_LF_CR_LF_LEN;
3668                                                         }
3669                                                 }
3670
3671                                                 //set data state HTTP_HEADER
3672                                                 session_data_ptr->data_state = HTTP_HEADER;
3673                                         }
3674                                 }
3675                         }
3676                         //data state is UNKNOWN
3677                         else if (session_data_ptr->data_state == UNKNOWN) {
3678                                 //set current message rest size
3679                                 session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3680                         } else {
3681                                 //none
3682                         }
3683
3684                         //data state is HTTP_START
3685                         if (session_data_ptr->data_state == HTTP_START) {
3686                                 //set return status
3687                                 status = REALSERVER_RECV;
3688                         }
3689                         //data state is not HTTP_START
3690                         else {
3691                                 //set return status
3692                                 status = CLIENT_CONNECTION_CHECK;
3693                         }
3694                 }
3695
3696                 //set last status
3697                 session_data_ptr->last_status = status;
3698         } catch (int e) {
3699                 /*-------- DEBUG LOG --------*/
3700                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3701                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3702                                                 "handle_realserver_recv() : catch exception e = %d. thread id : %d.");
3703                         formatter % e % boost::this_thread::get_id();
3704                         putLogDebug(600111, formatter.str(), __FILE__, __LINE__);
3705                 }
3706                 /*------DEBUG LOG END------*/
3707
3708                 //set return status
3709                 status = FINALIZE;
3710         } catch (const boost::bad_lexical_cast &) {
3711                 std::cerr << "protocol_module_ip::handle_realserver_recv() : exception : " <<  "Content_Length field's value is invalid." << std::endl;
3712                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_recv() : "
3713                                         "Content_Length field's value is invalid. thread id : %d.");
3714                 formatter % boost::this_thread::get_id();
3715                 putLogError(600071, formatter.str(), __FILE__, __LINE__);
3716
3717                 //set return status
3718                 status = FINALIZE;
3719         } catch (const std::exception &ex) {
3720                 std::cerr << "protocol_module_ip::handle_realserver_recv() : exception : error = " << ex.what() << "." << std::endl;
3721                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3722                                         "handle_realserver_recv() : exception : error = %s. thread id : %d.");
3723                 formatter % ex.what() % boost::this_thread::get_id();
3724                 putLogError(600072, formatter.str(), __FILE__, __LINE__);
3725
3726                 //set return status
3727                 status = FINALIZE;
3728         } catch (...) {
3729                 std::cerr << "protocol_module_ip::handle_realserver_recv() : Unknown exception." << std::endl;
3730                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
3731                                         "protocol_module_ip::handle_realserver_recv() : "
3732                                         "Unknown exception. thread id : %d.");
3733                 formatter % boost::this_thread::get_id();
3734                 putLogError(600073, formatter.str(), __FILE__, __LINE__);
3735
3736                 //set return status
3737                 status = FINALIZE;
3738         }
3739
3740         /*-------- DEBUG LOG --------*/
3741         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3742                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3743                                         "handle_realserver_recv(const boost::thread::id thread_id, "
3744                                         "const boost::asio::ip::tcp::endpoint& rs_endpoint, "
3745                                         "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3746                                         "const size_t recvlen) : return_value = %d. thread id : %d.");
3747                 formatter % FINALIZE % boost::this_thread::get_id();
3748                 putLogDebug(600112, formatter.str(), __FILE__, __LINE__);
3749         }
3750         /*------DEBUG LOG END------*/
3751
3752         return status;
3753 }
3754
3755
3756
3757 //! called from after sorryserver receive
3758 //! @param[in]    downstream thread id
3759 //! @param[in]    sorryserver endpoint reference
3760 //! @param[in]    receive from realserver buffer reference.
3761 //! @param[in]    recv data length
3762 //! @return     session use EVENT mode
3763 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_recv(
3764         const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &sorry_endpoint, const boost::array <
3765         char, MAX_BUFFER_SIZE > & recvbuffer, const size_t recvlen)
3766 {
3767         /*-------- DEBUG LOG --------*/
3768         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3769                 size_t buffer_size = recvbuffer.size() < recvlen ? recvbuffer.size() : recvlen;
3770                 std::string buffer;
3771                 dump_memory(recvbuffer.data(), buffer_size, buffer);
3772                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3773                                         "handle_sorryserver_recv(const boost::thread::id thread_id, "
3774                                         "const boost::asio::ip::tcp::endpoint& sorry_endpoint, "
3775                                         "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3776                                         "const size_t recvlen) : thread_id = %d, sorry_endpoint = [%s]:%d, recvbuffer = %s, recvlen = %d.");
3777                 formatter % thread_id % sorry_endpoint.address().to_string() % sorry_endpoint.port()
3778                 % buffer % recvlen;
3779                 putLogDebug(600113, formatter.str(), __FILE__, __LINE__);
3780         }
3781         /*------DEBUG LOG END------*/
3782
3783         EVENT_TAG status                = FINALIZE;
3784         bool find_ret                    = false;
3785         size_t http_header_offset            = 0;
3786         size_t http_header_len                = 0;
3787         size_t http_header_content_length_offset    = 0;
3788         size_t http_header_content_length_len        = 0;
3789         int content_length_value            = 0;
3790         const size_t CR_LF_LEN                = 2; //length of "\r\n"
3791         const size_t CR_LF_CR_LF_LEN            = 4; //length of "\r\n\r\n"
3792
3793         session_thread_data_map_it            session_thread_it;
3794         thread_data_ptr                    session_data_ptr;
3795         http_utility::CHECK_RESULT_TAG            check_ret;
3796         std::string                    content_length;
3797         cmatch                        regex_ret;
3798         cregex content_length_regex = icase("Content-Length") >> ":" >> *~_d >> (s1 = +_d) >> *~_d;
3799
3800         if (unlikely(recvlen > recvbuffer.size())) {
3801                 std::cerr << "protocol_module_ip::handle_sorryserver_recv() : Data size bigger than buffer size." << std::endl;
3802                 boost::format formatter("Data size bigger than buffer size. thread id : %d.");
3803                 formatter % boost::this_thread::get_id();
3804                 putLogError(600074, formatter.str(), __FILE__, __LINE__);
3805
3806                 /*-------- DEBUG LOG --------*/
3807                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3808                         boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3809                                                 "handle_sorryserver_recv(const boost::thread::id thread_id, "
3810                                                 "const boost::asio::ip::tcp::endpoint& sorry_endpoint, "
3811                                                 "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3812                                                 "const size_t recvlen) : return_value = %d. thread id : %d.");
3813                         formatter % FINALIZE % boost::this_thread::get_id();
3814                         putLogDebug(600114, formatter.str(), __FILE__, __LINE__);
3815                 }
3816                 /*------DEBUG LOG END------*/
3817
3818                 return status;
3819         }
3820
3821         try {
3822                 {
3823                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
3824
3825                         session_thread_it = session_thread_data_map.find(thread_id);
3826                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
3827                                 boost::format formatter("Invalid thread id. thread id : %d.");
3828                                 formatter % boost::this_thread::get_id();
3829                                 putLogError(600075, formatter.str(), __FILE__, __LINE__);
3830                                 throw - 1;
3831                         }
3832
3833                         session_data_ptr = session_thread_it->second;
3834                 }
3835
3836                 //set switch flag off
3837                 session_data_ptr->switch_flag = SWITCH_FLAG_OFF;
3838
3839                 /*-------- DEBUG LOG --------*/
3840                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3841                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3842                                                 "handle_sorryserver_recv(const boost::thread::id thread_id, "
3843                                                 "const boost::asio::ip::tcp::endpoint& sorry_endpoint, "
3844                                                 "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3845                                                 "const size_t recvlen) : SWITCH_FLAG_OFF. "
3846                                                 "thread_id = %d, rs_endpoint = [%s]:%d.");
3847                         formatter % thread_id % sorry_endpoint.address().to_string() % sorry_endpoint.port();
3848                         putLogDebug(600115, formatter.str(), __FILE__, __LINE__);
3849                 }
3850                 /*------DEBUG LOG END------*/
3851
3852                 //copy data from recvbuffer
3853                 if (!get_data_from_recvbuffer(session_data_ptr, recvbuffer, recvlen)) {
3854                         //copy failed
3855                         std::cerr << "protocol_module_ip::handle_sorryserver_recv() : Data size bigger than buffer size." << std::endl;
3856                         boost::format formatter("Data size bigger than buffer size. thread id : % id.");
3857                         formatter % boost::this_thread::get_id();
3858                         putLogError(600076, formatter.str(), __FILE__, __LINE__);
3859
3860                         status = FINALIZE;
3861                 } else {
3862                         if (forwarded_for == FORWARDED_FOR_OFF && session_data_ptr->sorry_flag == SORRY_FLAG_OFF) {
3863                                 session_data_ptr->data_state = UNKNOWN;
3864                         }
3865                         //data state is HTTP_START
3866                         if (session_data_ptr->data_state == HTTP_START) {
3867                                 //search http header
3868                                 find_ret = http_utility::find_http_header_all(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3869                                                 session_data_ptr->data_length,
3870                                                 http_header_offset,
3871                                                 http_header_len
3872                                                                              );
3873
3874                                 /*-------- DEBUG LOG --------*/
3875                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3876                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3877                                                                 "handle_sorryserver_recv() : call find_http_header_all : "
3878                                                                 "return_value = %d. thread id : %d.");
3879                                         formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
3880                                         putLogDebug(600116, formatter.str(), __FILE__, __LINE__);
3881                                 }
3882                                 /*------DEBUG LOG END------*/
3883
3884                                 //search http header result is NG
3885                                 if (!find_ret) {
3886                                         //data size bigger than max buffer size
3887                                         if (session_data_ptr->data_length >= MAX_IP_MODULE_BUFFER_SIZE - recvbuffer.size()) {
3888                                                 //set data state UNKNOWN
3889                                                 session_data_ptr->data_state = UNKNOWN;
3890                                                 //set current message rest size
3891                                                 session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3892                                         }
3893                                 }
3894                                 //search http header result is OK
3895                                 else {
3896                                         //check http version and status code
3897                                         check_ret = http_utility::check_http_version_and_status_code(session_data_ptr->data_buffer,
3898                                                         session_data_ptr->data_length);
3899
3900                                         /*-------- DEBUG LOG --------*/
3901                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3902                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3903                                                                         "handle_sorryserver_recv() : call check_http_version_and_status_code : "
3904                                                                         "return_value = %d. thread id : %d.");
3905                                                 formatter % check_ret % boost::this_thread::get_id();
3906                                                 putLogDebug(600117, formatter.str(), __FILE__, __LINE__);
3907                                         }
3908                                         /*------DEBUG LOG END------*/
3909
3910                                         //check http version and status code result is NG
3911                                         if (check_ret == http_utility::CHECK_NG) {
3912                                                 //set data state UNKNOWN
3913                                                 session_data_ptr->data_state = UNKNOWN;
3914                                                 //set current message rest size
3915                                                 session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3916                                         }
3917                                         //check http version and status code result is OK
3918                                         else {
3919                                                 //search Content_Length header
3920                                                 find_ret = http_utility::find_http_header_content_length(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3921                                                                 session_data_ptr->data_length,
3922                                                                 http_header_content_length_offset,
3923                                                                 http_header_content_length_len);
3924
3925                                                 /*-------- DEBUG LOG --------*/
3926                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3927                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3928                                                                                 "handle_sorryserver_recv() : call find_http_header_content_length : "
3929                                                                                 "return_value = %d. thread id : %d.");
3930                                                         formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
3931                                                         putLogDebug(600118, formatter.str(), __FILE__, __LINE__);
3932                                                 }
3933                                                 /*------DEBUG LOG END------*/
3934
3935                                                 //search Content_Length result is OK
3936                                                 if (find_ret) {
3937                                                         ////set content length string
3938                                                         content_length.assign(session_data_ptr->data_buffer + session_data_ptr->data_offset + http_header_content_length_offset,
3939                                                                               http_header_content_length_len);
3940                                                         find_ret = regex_search(content_length.c_str(), regex_ret, content_length_regex);
3941
3942                                                         //"content-length: ddd\r\n"
3943                                                         if (find_ret) {
3944                                                                 content_length = content_length.substr(
3945                                                                                          regex_ret.position(1),
3946                                                                                          regex_ret.length(1));
3947
3948                                                                 //set content length value
3949                                                                 content_length_value = boost::lexical_cast<int>(content_length);
3950                                                         }
3951
3952                                                         //http_header context is "\r\n\r\n" only
3953                                                         if (http_header_len == 0) {
3954                                                                 //set current message rest size
3955                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + content_length_value + CR_LF_LEN;
3956                                                         } else {
3957                                                                 //set current message rest size
3958                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + content_length_value + CR_LF_CR_LF_LEN;
3959                                                         }
3960                                                 }
3961                                                 //search Content_Length result is NG
3962                                                 else {
3963                                                         //http_header context is "\r\n\r\n" only
3964                                                         if (http_header_len == 0) {
3965                                                                 //set current message rest size
3966                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + CR_LF_LEN;
3967                                                         } else {
3968                                                                 //set current message rest size
3969                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + CR_LF_CR_LF_LEN;
3970                                                         }
3971
3972                                                 }
3973
3974                                                 //set data state HTTP_HEADER
3975                                                 session_data_ptr->data_state = HTTP_HEADER;
3976
3977                                         }
3978                                 }
3979                         }
3980                         //data state is UNKNOWN
3981                         else if (session_data_ptr->data_state == UNKNOWN) {
3982                                 //set current message rest size
3983                                 session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3984                         } else {
3985                                 //none
3986                         }
3987
3988                         //data state is HTTP_START
3989                         if (session_data_ptr->data_state == HTTP_START) {
3990                                 //set return status
3991                                 status = SORRYSERVER_RECV;
3992                         }
3993                         //data state is not HTTP_START
3994                         else {
3995                                 //set return status
3996                                 status = CLIENT_CONNECTION_CHECK;
3997                         }
3998                 }
3999
4000                 //set last status
4001                 session_data_ptr->last_status = status;
4002         } catch (int e) {
4003                 /*-------- DEBUG LOG --------*/
4004                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4005                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4006                                                 "handle_sorryserver_recv() : catch exception e = %d. thread id : %d.");
4007                         formatter % e % boost::this_thread::get_id();
4008                         putLogDebug(600119, formatter.str(), __FILE__, __LINE__);
4009                 }
4010                 /*------DEBUG LOG END------*/
4011
4012                 //set return status
4013                 status = FINALIZE;
4014         } catch (const boost::bad_lexical_cast &) {
4015                 std::cerr << "protocol_module_ip::handle_sorryserver_recv() : exception : " <<  "Content_Length field's value is invalid." << std::endl;
4016                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_recv() : "
4017                                         "Content_Length field's value is invalid. thread id : %d.");
4018                 formatter % boost::this_thread::get_id();
4019                 putLogError(600077, formatter.str(), __FILE__, __LINE__);
4020
4021                 //set return status
4022                 status = FINALIZE;
4023         } catch (const std::exception &ex) {
4024                 std::cerr << "protocol_module_ip::handle_sorryserver_recv() : exception : error = " << ex.what() << "." << std::endl;
4025                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4026                                         "handle_sorryserver_recv() : exception : error = %s. thread id : %d.");
4027                 formatter % ex.what() % boost::this_thread::get_id();
4028                 putLogError(600078, formatter.str(), __FILE__, __LINE__);
4029
4030                 //set return status
4031                 status = FINALIZE;
4032         } catch (...) {
4033                 std::cerr << "protocol_module_ip::handle_sorryserver_recv() : Unknown exception." << std::endl;
4034                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
4035                                         "protocol_module_ip::handle_sorryserver_recv() : "
4036                                         "Unknown exception. thread id : %d.");
4037                 formatter % boost::this_thread::get_id();
4038                 putLogError(600079, formatter.str(), __FILE__, __LINE__);
4039
4040                 //set return status
4041                 status = FINALIZE;
4042         }
4043
4044         /*-------- DEBUG LOG --------*/
4045         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4046                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4047                                         "handle_sorryserver_recv(const boost::thread::id thread_id, "
4048                                         "const boost::asio::ip::tcp::endpoint& sorry_endpoint, "
4049                                         "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
4050                                         "const size_t recvlen) : return_value = %d. thread id : %d.");
4051                 formatter % FINALIZE % boost::this_thread::get_id();
4052                 putLogDebug(600120, formatter.str(), __FILE__, __LINE__);
4053         }
4054         /*------DEBUG LOG END------*/
4055
4056         return status;
4057
4058 }
4059
4060 //! called from UPSTREAM thread. make module original message.
4061 //! @param[in]    downstream thread id.
4062 //! @return     session use EVENT mode
4063 protocol_module_base::EVENT_TAG protocol_module_ip::handle_response_send_inform(
4064         const boost::thread::id thread_id)
4065 {
4066         /*-------- DEBUG LOG --------*/
4067         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4068                 boost::format formatter("in/out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4069                                         "handle_response_send_inform(const boost::thread::id thread_id) : "
4070                                         "return_value = %d. thread id : %d.");
4071                 formatter % STOP % boost::this_thread::get_id();
4072                 putLogDebug(600121, formatter.str(), __FILE__, __LINE__);
4073         }
4074         /*------DEBUG LOG END------*/
4075
4076         return STOP;
4077 }
4078
4079 //! called from after client connection check. use TCP/IP only. create client send message.
4080 //! @param[in]    downstream thread id
4081 //! @param[out]    send buffer reference
4082 //! @param[out]    send data length
4083 //! @return     session use EVENT mode
4084 protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_connection_check(
4085         const boost::thread::id thread_id, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen)
4086 {
4087         /*-------- DEBUG LOG --------*/
4088         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4089                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4090                                         "handle_client_connection_check(const boost::thread::id thread_id, "
4091                                         "boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t& datalen) : "
4092                                         "thread_id = %d.");
4093                 formatter % thread_id;
4094                 putLogDebug(600122, formatter.str(), __FILE__, __LINE__);
4095         }
4096         /*------DEBUG LOG END------*/
4097
4098         EVENT_TAG status = FINALIZE;
4099         thread_data_ptr session_data_ptr;
4100         size_t send_possible_size = 0;
4101
4102         try {
4103                 {
4104                         boost::mutex::scoped_lock sclock(session_thread_data_map_mutex);
4105
4106                         session_thread_data_map_it session_thread_it = session_thread_data_map.find(thread_id);
4107                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
4108                                 boost::format formatter("Invalid thread id. thread id : %d.");
4109                                 formatter % boost::this_thread::get_id();
4110                                 putLogError(600080, formatter.str(), __FILE__, __LINE__);
4111                                 throw - 1;
4112                         }
4113
4114                         session_data_ptr = session_thread_it->second;
4115                 }
4116
4117                 //data state is HTTP_HEADER
4118                 if (session_data_ptr->data_state == HTTP_HEADER) {
4119                         //set data HTTP_BODY
4120                         session_data_ptr->data_state = HTTP_BODY;
4121                 }
4122
4123                 //set send possible data size
4124                 send_possible_size = std::min(std::min(sendbuffer.size(), session_data_ptr->current_message_rest_size),
4125                                               session_data_ptr->data_length
4126                                              );
4127                 //set send data size
4128                 datalen = send_possible_size;
4129
4130                 /*-------- DEBUG LOG --------*/
4131                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4132                         std::string datadump;
4133                         dump_memory(session_data_ptr->data_buffer + session_data_ptr->data_offset, send_possible_size, datadump);
4134
4135                         boost::format formatter(
4136                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4137                                 "handle_client_connection_check() : before memcpy (data dump) : "
4138                                 "data begin = %d, data_size = %d, data = %s");
4139                         formatter % session_data_ptr->data_offset % send_possible_size % datadump;
4140                         putLogDebug(600123, formatter.str(), __FILE__, __LINE__);
4141                 }
4142                 /*------DEBUG LOG END------*/
4143
4144                 //copy send possible data to sendbuffer
4145                 memcpy(sendbuffer.data(), session_data_ptr->data_buffer + session_data_ptr->data_offset,
4146                        send_possible_size);
4147
4148                 /*-------- DEBUG LOG --------*/
4149                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4150                         std::string datadump;
4151                         dump_memory(sendbuffer.data(), send_possible_size, datadump);
4152
4153                         boost::format formatter(
4154                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4155                                 "handle_client_connection_check() : after memcpy (data dump) : "
4156                                 "data begin = 0, data_size = %d, data = %s");
4157                         formatter % send_possible_size % datadump;
4158                         putLogDebug(600124, formatter.str(), __FILE__, __LINE__);
4159                 }
4160                 /*------DEBUG LOG END------*/
4161
4162                 //set current message rest size
4163                 session_data_ptr->current_message_rest_size -= send_possible_size;
4164
4165                 //set buffer's position
4166                 session_data_ptr->data_offset += send_possible_size;
4167                 session_data_ptr->data_length -= send_possible_size;
4168
4169                 //current message rest size is 0
4170                 if (session_data_ptr->current_message_rest_size == 0) {
4171                         boost::mutex::scoped_lock lock(session_data_mutex);
4172                         time_t now;
4173                         time(&now);
4174                         boost::asio::ip::tcp::endpoint init_endpoint;
4175
4176                         //write session data to session table
4177                         ip_data_processor->write_session_data(session_data_ptr->ip_hash,
4178                                                               init_endpoint,
4179                                                               now);
4180
4181                 }
4182
4183                 //set return status
4184                 status = CLIENT_SEND;
4185
4186                 //set last status
4187                 session_data_ptr->last_status = status;
4188         } catch (int e) {
4189                 /*-------- DEBUG LOG --------*/
4190                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4191                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4192                                                 "handle_client_connection_check() : catch exception e = %d. thread id : %d.");
4193                         formatter % e % boost::this_thread::get_id();
4194                         putLogDebug(600125, formatter.str(), __FILE__, __LINE__);
4195                 }
4196                 /*------DEBUG LOG END------*/
4197
4198                 //set return status
4199                 status = FINALIZE;
4200         } catch (const std::exception &ex) {
4201                 std::cerr << "protocol_module_ip::handle_client_connection_check() : exception : error = " << ex.what() << "." << std::endl;
4202                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4203                                         "handle_client_connection_check() : exception : error = %s. thread id : %d.");
4204                 formatter % ex.what() % boost::this_thread::get_id();
4205                 putLogError(600081, formatter.str(), __FILE__, __LINE__);
4206
4207                 //set return status
4208                 status = FINALIZE;
4209         } catch (...) {
4210                 std::cerr << "protocol_module_ip::handle_client_connection_check() : Unknown exception." << std::endl;
4211                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4212                                         "handle_client_connection_check() : Unknown exception. thread id : %d.");
4213                 formatter % boost::this_thread::get_id();
4214                 putLogError(600082, formatter.str(), __FILE__, __LINE__);
4215
4216                 //set return status
4217                 status = FINALIZE;
4218         }
4219
4220         /*-------- DEBUG LOG --------*/
4221         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4222                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4223                                         "handle_client_connection_check(const boost::thread::id thread_id, "
4224                                         "boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t& datalen) : return_value = %d. thread id : %d.");
4225                 formatter % status % boost::this_thread::get_id();
4226                 putLogDebug(600126, formatter.str(), __FILE__, __LINE__);
4227         }
4228         /*------DEBUG LOG END------*/
4229
4230         return status;
4231 }
4232
4233 //! called from after client select. use UDP only
4234 //! @param[in]    downstream thread id
4235 //!    @param[in]    client udp endpoint
4236 //! @param[out]    send buffer reference
4237 //! @param[out]    send data length
4238 //! @return     session use EVENT mode
4239 protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_select(
4240         const boost::thread::id thread_id, boost::asio::ip::udp::endpoint &cl_endpoint, boost::array < char,
4241         MAX_BUFFER_SIZE > & sendbuffer, size_t &datalen)
4242 {
4243         /*-------- DEBUG LOG --------*/
4244         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4245                 boost::format formatter("in/out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4246                                         "handle_client_select(const boost::thread::id thread_id, "
4247                                         "boost::asio::ip::udp::endpoint& cl_endpoint, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
4248                                         "const size_t& datalen) : "
4249                                         "return_value = %d. thread id : %d.");
4250                 formatter % STOP % boost::this_thread::get_id();
4251                 putLogDebug(600127, formatter.str(), __FILE__, __LINE__);
4252         }
4253         /*------DEBUG LOG END------*/
4254         return STOP;
4255 }
4256
4257 //!    called from after client send
4258 //!    @param[in]    downstream thread id
4259 //! @return     session use EVENT mode
4260 protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_send(
4261         const boost::thread::id thread_id)
4262 {
4263         /*-------- DEBUG LOG --------*/
4264         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4265                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4266                                         "handle_client_send(const boost::thread::id thread_id) : thread_id = %d.");
4267                 formatter % thread_id;
4268                 putLogDebug(600128, formatter.str(), __FILE__, __LINE__);
4269         }
4270         /*------DEBUG LOG END------*/
4271
4272         EVENT_TAG status = FINALIZE;
4273         size_t http_header_all_offset        = 0;
4274         size_t http_header_all_len        = 0;
4275         size_t http_header_content_length_offset = 0;
4276         size_t http_header_content_length_len    = 0;
4277         const size_t CR_LF_LEN             = 2;
4278         const size_t CR_LF_CR_LF_LEN        = 4;
4279         int content_length_value        = 0;
4280
4281         std::string content_length;
4282         cmatch regex_ret;
4283         cregex content_length_regex = icase("Content-Length") >> ":" >> *~_d >> (s1 = +_d) >> *~_d;
4284
4285
4286         bool find_ret = false;
4287         http_utility::CHECK_RESULT_TAG check_ret;
4288
4289         thread_data_ptr session_data_ptr;
4290         session_thread_data_map_it session_thread_it;
4291
4292         try {
4293                 {
4294                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
4295
4296                         //thread id check
4297                         session_thread_it = session_thread_data_map.find(thread_id);
4298                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
4299                                 boost::format formatter("Invalid thread id. thread id : %d.");
4300                                 formatter % boost::this_thread::get_id();
4301                                 putLogError(600083, formatter.str(), __FILE__, __LINE__);
4302                                 throw - 1;
4303                         }
4304
4305                         session_data_ptr = session_thread_it->second;
4306                 }
4307
4308                 //current_message_rest_size > 0
4309                 if (session_data_ptr->current_message_rest_size > 0) {
4310                         //data size > 0
4311                         if (session_data_ptr->data_length > 0) {
4312                                 //set return status
4313                                 status = CLIENT_CONNECTION_CHECK;
4314                         }
4315                         //data size is 0
4316                         else {
4317                                 //data offset is 0
4318                                 session_data_ptr->data_offset = 0;
4319
4320                                 //set return status
4321                                 status = REALSERVER_RECV;
4322                         }
4323                 }
4324                 //current_message_rest_size is 0
4325                 else {
4326                         //data size > 0
4327                         if (session_data_ptr->data_length > 0) {
4328                                 //data state is HTTP_BODY
4329                                 if (session_data_ptr->data_state == HTTP_BODY) {
4330                                         //search whole http header, get whole http header's offset and length
4331                                         find_ret = http_utility::find_http_header_all(session_data_ptr->data_buffer + session_data_ptr->data_offset,
4332                                                         session_data_ptr->data_length,
4333                                                         http_header_all_offset,
4334                                                         http_header_all_len
4335                                                                                      );
4336
4337                                         /*-------- DEBUG LOG --------*/
4338                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4339                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4340                                                                         "handle_client_send() : call find_http_header_all : "
4341                                                                         "return_value = %d. thread id : %d.");
4342                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
4343                                                 putLogDebug(600129, formatter.str(), __FILE__, __LINE__);
4344                                         }
4345                                         /*------DEBUG LOG END------*/
4346
4347                                         //search http header result is NG
4348                                         if (!find_ret) {
4349                                                 //set data state HTTP_START
4350                                                 session_data_ptr->data_state = HTTP_START;
4351
4352                                                 //set return status
4353                                                 status = REALSERVER_RECV;
4354                                         }
4355                                         //search http header result is OK
4356                                         else {
4357                                                 //check http version and status code
4358                                                 check_ret = http_utility::check_http_version_and_status_code(session_data_ptr->data_buffer + session_data_ptr->data_offset,
4359                                                                 session_data_ptr->data_length);
4360
4361                                                 /*-------- DEBUG LOG --------*/
4362                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4363                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4364                                                                                 "handle_client_send() : call check_http_version_and_status_code : "
4365                                                                                 "return_value = %d. thread id : %d.");
4366                                                         formatter % check_ret % boost::this_thread::get_id();
4367                                                         putLogDebug(600130, formatter.str(), __FILE__, __LINE__);
4368                                                 }
4369                                                 /*------DEBUG LOG END------*/
4370
4371                                                 //check version and status code result is NG
4372                                                 if (check_ret == http_utility::CHECK_NG) {
4373                                                         //set current message rest size
4374                                                         session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
4375
4376                                                         //set data state UNKNOWN
4377                                                         session_data_ptr->data_state = UNKNOWN;
4378                                                 }
4379                                                 //check version and status code result is OK
4380                                                 else {
4381                                                         //search Content_Length header
4382                                                         find_ret = http_utility::find_http_header_content_length(session_data_ptr->data_buffer + session_data_ptr->data_offset,
4383                                                                         session_data_ptr->data_length,
4384                                                                         http_header_content_length_offset,
4385                                                                         http_header_content_length_len);
4386
4387                                                         /*-------- DEBUG LOG --------*/
4388                                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4389                                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4390                                                                                         "handle_client_send() : call find_http_header_content_length : "
4391                                                                                         "return_value = %d. thread id : %d.");
4392                                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
4393                                                                 putLogDebug(600131, formatter.str(), __FILE__, __LINE__);
4394                                                         }
4395                                                         /*------DEBUG LOG END------*/
4396
4397                                                         //search Content_Length result is OK
4398                                                         if (find_ret) {
4399                                                                 content_length.assign(session_data_ptr->data_buffer + session_data_ptr->data_offset + http_header_content_length_offset,
4400                                                                                       http_header_content_length_len);
4401                                                                 find_ret = regex_search(content_length.c_str(), regex_ret, content_length_regex);
4402
4403                                                                 //"content-length: ddd\r\n"
4404                                                                 if (find_ret) {
4405                                                                         content_length = content_length.substr(
4406                                                                                                  regex_ret.position(1),
4407                                                                                                  regex_ret.length(1));
4408
4409                                                                         //set content length value
4410                                                                         content_length_value = boost::lexical_cast<int>(content_length);
4411                                                                 }
4412
4413                                                                 //http_header context is "\r\n\r\n" only
4414                                                                 if (http_header_all_len == 0) {
4415                                                                         //set current message rest size
4416                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + content_length_value + CR_LF_LEN;
4417                                                                 } else {
4418                                                                         //set current message rest size
4419                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + content_length_value + CR_LF_CR_LF_LEN;
4420                                                                 }
4421                                                         }
4422                                                         //search Content_Length result is OK
4423                                                         else {
4424                                                                 //http_header context is "\r\n\r\n" only
4425                                                                 if (http_header_all_len == 0) {
4426                                                                         //set current message rest size
4427                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + CR_LF_LEN;
4428                                                                 } else {
4429                                                                         //set current message rest size
4430                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + CR_LF_CR_LF_LEN;
4431                                                                 }
4432
4433                                                         }
4434
4435                                                         //set data state HTTP_HEADER
4436                                                         session_data_ptr->data_state = HTTP_HEADER;
4437                                                 }
4438
4439                                                 //set return status
4440                                                 status = CLIENT_CONNECTION_CHECK;
4441                                         }
4442                                 }
4443                                 //data state is UNKNOWN
4444                                 else if (session_data_ptr->data_state == UNKNOWN) {
4445                                         //set return status
4446                                         status = CLIENT_CONNECTION_CHECK;
4447                                 }
4448                         }
4449                         //data size is 0
4450                         else {
4451                                 //data state is HTTP_BODY
4452                                 if (session_data_ptr->data_state == HTTP_BODY) {
4453                                         //set data state HTTP_START
4454                                         session_data_ptr->data_state = HTTP_START;
4455                                 }
4456
4457                                 //set data offset 0
4458                                 session_data_ptr->data_offset = 0;
4459
4460                                 //set return status
4461                                 status = REALSERVER_RECV;
4462                         }
4463                 }
4464
4465                 //switch flag is on and status is REALSERVER_RECV
4466                 if (session_data_ptr->switch_flag == SWITCH_FLAG_ON
4467                     && status == REALSERVER_RECV) {
4468                         //set return status
4469                         status = CLIENT_DISCONNECT;
4470                 }
4471                 //sorry flag is on and and status is REALSERVER_RECV
4472                 else if (session_data_ptr->sorry_flag == SORRY_FLAG_ON
4473                          && status == REALSERVER_RECV) {
4474                         //set return status
4475                         status = SORRYSERVER_RECV;
4476                 } else {
4477                         //none
4478                 }
4479
4480                 //set last status
4481                 session_data_ptr->last_status = status;
4482         } catch (int e) {
4483                 /*-------- DEBUG LOG --------*/
4484                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4485                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4486                                                 "handle_client_send() : catch exception e = %d. thread id : %d.");
4487                         formatter % e % boost::this_thread::get_id();
4488                         putLogDebug(600132, formatter.str(), __FILE__, __LINE__);
4489                 }
4490                 /*------DEBUG LOG END------*/
4491
4492                 //set last status
4493                 status = FINALIZE;
4494         } catch (const boost::bad_lexical_cast &) {
4495                 std::cerr << "protocol_module_ip::handle_client_send() : exception : " <<  "Content_Length field's value is invalid." << std::endl;
4496                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_send() : "
4497                                         "Content_Length field's value is invalid. thread id : %d.");
4498                 formatter % boost::this_thread::get_id();
4499                 putLogError(600084, formatter.str(), __FILE__, __LINE__);
4500
4501                 //set last status
4502                 status = FINALIZE;
4503         } catch (const std::exception &ex) {
4504                 std::cerr << "protocol_module_ip::handle_client_send() : exception : error = " << ex.what() << "." << std::endl;
4505                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4506                                         "handle_client_send() : exception : error = %s. thread id : %d.");
4507                 formatter % ex.what() % boost::this_thread::get_id();
4508                 putLogError(600085, formatter.str(), __FILE__, __LINE__);
4509
4510                 //set last status
4511                 status = FINALIZE;
4512         } catch (...) {
4513                 std::cerr << "protocol_module_ip::handle_client_send() : Unknown exception." << std::endl;
4514                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
4515                                         "protocol_module_ip::handle_client_send() : "
4516                                         "Unknown exception. thread id : %d.");
4517                 formatter % boost::this_thread::get_id();
4518                 putLogError(600086, formatter.str(), __FILE__, __LINE__);
4519
4520                 //set last status
4521                 status = FINALIZE;
4522         }
4523
4524         /*-------- DEBUG LOG --------*/
4525         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4526                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4527                                         "handle_client_send(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
4528                 formatter % status % boost::this_thread::get_id();
4529                 putLogDebug(600133, formatter.str(), __FILE__, __LINE__);
4530         }
4531         /*------DEBUG LOG END------*/
4532
4533         return status;
4534 }
4535
4536 //! call from client disconnect event. use upstream thread and downstream thread.
4537 //! @param[in]    upstream and downstream thread id( check! one thread one event! )
4538 //! @return     session use EVENT mode
4539 protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_disconnect(
4540         const boost::thread::id thread_id)
4541 {
4542         /*-------- DEBUG LOG --------*/
4543         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4544                 boost::format formatter("in/out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4545                                         "handle_client_disconnect(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
4546                 formatter % FINALIZE % boost::this_thread::get_id();
4547                 putLogDebug(600134, formatter.str(), __FILE__, __LINE__);
4548         }
4549         /*------DEBUG LOG END------*/
4550         return FINALIZE;
4551 }
4552
4553 //! call from sorry mode event. use upstream thread and downstream thread
4554 //! @param[in]    upstream and downstream thread id( check! one thread one event and first time call pattern )
4555 //! @return     session use EVENT mode
4556 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorry_enable(
4557         const boost::thread::id thread_id)
4558 {
4559         /*-------- DEBUG LOG --------*/
4560         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4561                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4562                                         "handle_sorry_enable(const boost::thread::id thread_id) : thread_id = %d.");
4563                 formatter % boost::this_thread::get_id();
4564                 putLogDebug(600135, formatter.str(), __FILE__, __LINE__);
4565         }
4566         /*------DEBUG LOG END------*/
4567
4568         EVENT_TAG status = FINALIZE;
4569         thread_data_ptr session_data_ptr;
4570
4571         try {
4572                 {
4573                         boost::mutex::scoped_lock sclock(session_thread_data_map_mutex);
4574
4575                         session_thread_data_map_it session_thread_it = session_thread_data_map.find(thread_id);
4576                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
4577                                 boost::format formatter("Invalid thread id. thread id : %d.");
4578                                 formatter % boost::this_thread::get_id();
4579                                 putLogError(600087, formatter.str(), __FILE__, __LINE__);
4580                                 throw - 1;
4581                         }
4582
4583                         session_data_ptr = session_thread_it->second;
4584                 }
4585
4586
4587                 //up thread
4588                 if (session_data_ptr->thread_division == THREAD_DIVISION_UP_STREAM) {
4589                         //accept_end_flag is off
4590                         if (session_data_ptr->accept_end_flag == ACCEPT_END_FLAG_OFF) {
4591                                 //set return status
4592                                 status = ACCEPT;
4593                         }
4594                         //accept_end_flag is on
4595                         else {
4596                                 //sorry flag is on
4597                                 if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
4598                                         //data state is HTTP_START or HTTP_HEADER
4599                                         if (session_data_ptr->data_state == HTTP_START
4600                                             || session_data_ptr->data_state == HTTP_HEADER) {
4601                                                 //set switch flag on
4602                                                 session_data_ptr->switch_flag = SWITCH_FLAG_ON;
4603
4604                                                 /*-------- DEBUG LOG --------*/
4605                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4606                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4607                                                                                 "handle_sorry_enable(const boost::thread::id thread_id) : SWITCH_FLAG_ON. thread id : %d.");
4608                                                         formatter % boost::this_thread::get_id();
4609                                                         putLogDebug(600136, formatter.str(), __FILE__, __LINE__);
4610                                                 }
4611                                                 /*------DEBUG LOG END------*/
4612
4613                                                 //set return status
4614                                                 status = SORRYSERVER_DISCONNECT;
4615                                         }
4616                                         //data state is HTTP_BODY or UNKNOWN
4617                                         else {
4618                                                 //set return status
4619                                                 status = session_data_ptr->last_status;
4620                                         }
4621                                 }
4622                                 //sorry flag is off
4623                                 else {
4624                                         //data state is HTTP_START or HTTP_HEADER
4625                                         if (session_data_ptr->data_state == HTTP_START
4626                                             || session_data_ptr->data_state == HTTP_HEADER) {
4627                                                 //set switch flag on
4628                                                 session_data_ptr->switch_flag = SWITCH_FLAG_ON;
4629
4630                                                 /*-------- DEBUG LOG --------*/
4631                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4632                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4633                                                                                 "handle_sorry_enable(const boost::thread::id thread_id) : SWITCH_FLAG_ON. thread id : %d.");
4634                                                         formatter % boost::this_thread::get_id();
4635                                                         putLogDebug(600137, formatter.str(), __FILE__, __LINE__);
4636                                                 }
4637                                                 /*------DEBUG LOG END------*/
4638                                         }
4639                                         //data state is HTTP_BODY or UNKNOWN
4640                                         else {
4641                                                 //set end flag on
4642                                                 session_data_ptr->end_flag = END_FLAG_ON;
4643
4644                                                 /*-------- DEBUG LOG --------*/
4645                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4646                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4647                                                                                 "handle_sorry_enable(const boost::thread::id thread_id) : END_FLAG_ON. thread id : %d.");
4648                                                         formatter % boost::this_thread::get_id();
4649                                                         putLogDebug(600138, formatter.str(), __FILE__, __LINE__);
4650                                                 }
4651                                                 /*------DEBUG LOG END------*/
4652                                         }
4653
4654                                         //set return status
4655                                         status = REALSERVER_DISCONNECT;
4656                                 }
4657                         }
4658                 }
4659                 //down thread
4660                 else {
4661                         //sorry flag is on
4662                         if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
4663                                 //set return status
4664                                 status = session_data_ptr->last_status;
4665                         }
4666                         //sorry flag is off
4667                         else {
4668                                 //data state is HTTP_START and data size is 0
4669                                 if (session_data_ptr->data_state == HTTP_START
4670                                     && session_data_ptr->data_length == 0) {
4671                                         //set return status
4672                                         status = SORRYSERVER_RECV;
4673                                 }
4674                                 //data state is HTTP_START and data size > 0
4675                                 else if (session_data_ptr->data_state == HTTP_START
4676                                          && session_data_ptr->data_length > 0) {
4677                                         //set return status
4678                                         status = REALSERVER_DISCONNECT;
4679                                 }
4680                                 //data state is HTTP_HEADER or HTTP_BODY
4681                                 else if (session_data_ptr->data_state == HTTP_HEADER
4682                                          || session_data_ptr->data_state == HTTP_BODY) {
4683                                         //set switch flag on
4684                                         session_data_ptr->switch_flag = SWITCH_FLAG_ON;
4685
4686                                         /*-------- DEBUG LOG --------*/
4687                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4688                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4689                                                                         "handle_sorry_enable(const boost::thread::id thread_id) : SWITCH_FLAG_ON. thread id : %d.");
4690                                                 formatter % boost::this_thread::get_id();
4691                                                 putLogDebug(600139, formatter.str(), __FILE__, __LINE__);
4692                                         }
4693                                         /*------DEBUG LOG END------*/
4694
4695                                         //set return status
4696                                         status = session_data_ptr->last_status;
4697                                 }
4698                                 //other
4699                                 else {
4700                                         //set return status
4701                                         status = REALSERVER_DISCONNECT;
4702                                 }
4703                         }
4704                 }
4705
4706                 //set sorry flag on
4707                 session_data_ptr->sorry_flag = SORRY_FLAG_ON;
4708
4709                 /*-------- DEBUG LOG --------*/
4710                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4711                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4712                                                 "handle_sorry_enable(const boost::thread::id thread_id) : SORRY_FLAG_ON. thread id : %d.");
4713                         formatter % boost::this_thread::get_id();
4714                         putLogDebug(600140, formatter.str(), __FILE__, __LINE__);
4715                 }
4716                 /*------DEBUG LOG END------*/
4717
4718                 //set last status
4719                 session_data_ptr->last_status = status;
4720
4721         } catch (int e) {
4722                 /*-------- DEBUG LOG --------*/
4723                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4724                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4725                                                 "handle_sorry_enable() : catch exception e = %d. thread id : %d.");
4726                         formatter % e % boost::this_thread::get_id();
4727                         putLogDebug(600141, formatter.str(), __FILE__, __LINE__);
4728                 }
4729                 /*------DEBUG LOG END------*/
4730
4731                 //set return status
4732                 status = FINALIZE;
4733         } catch (std::exception &ex) {
4734                 std::cerr << "protocol_module_ip::handle_sorry_enable() : exception : error = " << ex.what() << "." << std::endl;
4735                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4736                                         "handle_sorry_enable() : exception : error = %s. thread id : %d.");
4737                 formatter % ex.what() % boost::this_thread::get_id();
4738                 putLogError(600088, formatter.str(), __FILE__, __LINE__);
4739
4740                 //set return status
4741                 status = FINALIZE;
4742         } catch (...) {
4743                 std::cerr << "protocol_module_ip::handle_sorry_enable() : Unknown exception." << std::endl;
4744                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
4745                                         "protocol_module_ip::handle_sorry_enable() : "
4746                                         "Unknown exception. thread id : %d.");
4747                 formatter % boost::this_thread::get_id();
4748                 putLogError(600089, formatter.str(), __FILE__, __LINE__);
4749
4750                 //set return status
4751                 status = FINALIZE;
4752         }
4753
4754         /*-------- DEBUG LOG --------*/
4755         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4756                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4757                                         "handle_sorry_enable(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
4758                 formatter % status % boost::this_thread::get_id();
4759                 putLogDebug(600142, formatter.str(), __FILE__, __LINE__);
4760         }
4761         /*------DEBUG LOG END------*/
4762
4763         return status;
4764 }
4765
4766 //! call from sorry mode disable. use upstream thread and downstream thread.
4767 //! @param[in]    upstream and downstream thread id( check! one thread one event )
4768 //! @return     session use EVENT mode
4769 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorry_disable(
4770         const boost::thread::id thread_id)
4771 {
4772         /*-------- DEBUG LOG --------*/
4773         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4774                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4775                                         "handle_sorry_disable(const boost::thread::id thread_id) : thread_id = %d.");
4776                 formatter % boost::this_thread::get_id();
4777                 putLogDebug(600143, formatter.str(), __FILE__, __LINE__);
4778         }
4779         /*------DEBUG LOG END------*/
4780
4781         EVENT_TAG status = FINALIZE;
4782         thread_data_ptr session_data_ptr;
4783
4784         try {
4785                 {
4786                         boost::mutex::scoped_lock sclock(session_thread_data_map_mutex);
4787
4788                         session_thread_data_map_it session_thread_it = session_thread_data_map.find(thread_id);
4789                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
4790                                 boost::format formatter("Invalid thread id. thread id : %d.");
4791                                 formatter % boost::this_thread::get_id();
4792                                 putLogError(600090, formatter.str(), __FILE__, __LINE__);
4793                                 throw - 1;
4794                         }
4795
4796                         session_data_ptr = session_thread_it->second;
4797                 }
4798
4799                 //up thread
4800                 if (session_data_ptr->thread_division == THREAD_DIVISION_UP_STREAM) {
4801                         //accept_end_flag is off
4802                         if (session_data_ptr->accept_end_flag == ACCEPT_END_FLAG_OFF) {
4803                                 //set return status
4804                                 status = ACCEPT;
4805                         }
4806                         //accept_end_flag is on
4807                         else {
4808                                 //sorry flag is on
4809                                 if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
4810                                         ///data state is HTTP_START or HTTP_HEADER
4811                                         if (session_data_ptr->data_state == HTTP_START
4812                                             || session_data_ptr->data_state == HTTP_HEADER) {
4813                                                 //set switch flag on
4814                                                 session_data_ptr->switch_flag = SWITCH_FLAG_ON;
4815
4816                                                 /*-------- DEBUG LOG --------*/
4817                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4818                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4819                                                                                 "handle_sorry_disable(const boost::thread::id thread_id) : SWITCH_FLAG_ON. thread id : %d.");
4820                                                         formatter % boost::this_thread::get_id();
4821                                                         putLogDebug(600144, formatter.str(), __FILE__, __LINE__);
4822                                                 }
4823                                                 /*------DEBUG LOG END------*/
4824
4825                                         }
4826                                         //data state is HTTP_BODY or UNKNOWN
4827                                         else {
4828                                                 //set end flag on
4829                                                 session_data_ptr->end_flag = END_FLAG_ON;
4830
4831                                                 /*-------- DEBUG LOG --------*/
4832                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4833                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4834                                                                                 "handle_sorry_disable(const boost::thread::id thread_id) : END_FLAG_ON. thread id : %d.");
4835                                                         formatter % boost::this_thread::get_id();
4836                                                         putLogDebug(600145, formatter.str(), __FILE__, __LINE__);
4837                                                 }
4838                                                 /*------DEBUG LOG END------*/
4839                                         }
4840
4841                                         //set return status
4842                                         status = SORRYSERVER_DISCONNECT;
4843
4844                                 }
4845                                 //sorry flag is off
4846                                 else {
4847                                         //data state is HTTP_START or HTTP_HEADER
4848                                         if (session_data_ptr->data_state == HTTP_START
4849                                             || session_data_ptr->data_state == HTTP_HEADER) {
4850                                                 //set switch flag on
4851                                                 session_data_ptr->switch_flag = SWITCH_FLAG_ON;
4852
4853                                                 /*-------- DEBUG LOG --------*/
4854                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4855                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4856                                                                                 "handle_sorry_disable(const boost::thread::id thread_id) : SWITCH_FLAG_ON. thread id : %d.");
4857                                                         formatter % boost::this_thread::get_id();
4858                                                         putLogDebug(600146, formatter.str(), __FILE__, __LINE__);
4859                                                 }
4860                                                 /*------DEBUG LOG END------*/
4861
4862                                                 //set return status
4863                                                 status = REALSERVER_DISCONNECT;
4864                                         }
4865                                         //data state is HTTP_BODY or UNKNOWN
4866                                         else {
4867                                                 //set return status
4868                                                 status = session_data_ptr->last_status;
4869                                         }
4870                                 }
4871                         }
4872                 }
4873                 //down thread
4874                 else {
4875                         //sorry flag is off
4876                         if (session_data_ptr->sorry_flag == SORRY_FLAG_OFF) {
4877                                 //set return status
4878                                 status = session_data_ptr->last_status;
4879                         }
4880                         //sorry flag is on
4881                         else {
4882                                 //data state is HTTP_START and data size is 0
4883                                 if (session_data_ptr->data_state == HTTP_START
4884                                     && session_data_ptr->data_length == 0) {
4885                                         //set return status
4886                                         status = REALSERVER_RECV;
4887                                 }
4888                                 //data state is HTTP_START and data size > 0
4889                                 else if (session_data_ptr->data_state == HTTP_START
4890                                          && session_data_ptr->data_length > 0) {
4891                                         //set return status
4892                                         status = SORRYSERVER_DISCONNECT;
4893                                 }
4894                                 //data state is HTTP_HEADER or HTTP_BODY
4895                                 else if (session_data_ptr->data_state == HTTP_HEADER
4896                                          || session_data_ptr->data_state == HTTP_BODY) {
4897                                         //set switch flag on
4898                                         session_data_ptr->switch_flag = SWITCH_FLAG_ON;
4899
4900                                         /*-------- DEBUG LOG --------*/
4901                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4902                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4903                                                                         "handle_sorry_disable(const boost::thread::id thread_id) : SWITCH_FLAG_ON. thread id : %d.");
4904                                                 formatter % boost::this_thread::get_id();
4905                                                 putLogDebug(600147, formatter.str(), __FILE__, __LINE__);
4906                                         }
4907                                         /*------DEBUG LOG END------*/
4908
4909                                         //set return status
4910                                         status = session_data_ptr->last_status;
4911                                 }
4912                                 //other
4913                                 else {
4914                                         //set return status
4915                                         status = SORRYSERVER_DISCONNECT;
4916                                 }
4917                         }
4918                 }
4919
4920                 //set sorry flag off
4921                 session_data_ptr->sorry_flag = SORRY_FLAG_OFF;
4922
4923                 /*-------- DEBUG LOG --------*/
4924                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4925                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4926                                                 "handle_sorry_disable(const boost::thread::id thread_id) : SORRY_FLAG_OFF. thread id : %d.");
4927                         formatter % boost::this_thread::get_id();
4928                         putLogDebug(600148, formatter.str(), __FILE__, __LINE__);
4929                 }
4930                 /*------DEBUG LOG END------*/
4931
4932                 //set last status
4933                 session_data_ptr->last_status = status;
4934         } catch (int e) {
4935                 /*-------- DEBUG LOG --------*/
4936                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4937                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4938                                                 "handle_sorry_disable() : catch exception e = %d. thread id : %d.");
4939                         formatter % e % boost::this_thread::get_id();
4940                         putLogDebug(600149, formatter.str(), __FILE__, __LINE__);
4941                 }
4942                 /*------DEBUG LOG END------*/
4943
4944                 //set last status
4945                 status = FINALIZE;
4946         } catch (std::exception &ex) {
4947                 std::cerr << "protocol_module_ip::handle_sorry_disable() : exception : error = " << ex.what() << "." << std::endl;
4948                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4949                                         "handle_sorry_disable() : exception : error = %s. thread id : %d.");
4950                 formatter % ex.what() % boost::this_thread::get_id();
4951                 putLogError(600091, formatter.str(), __FILE__, __LINE__);
4952
4953                 //set last status
4954                 status = FINALIZE;
4955         } catch (...) {
4956                 std::cerr << "protocol_module_ip::handle_sorry_disable() : Unknown exception." << std::endl;
4957                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
4958                                         "protocol_module_ip::handle_sorry_disable() : "
4959                                         "Unknown exception. thread id : %d.");
4960                 formatter % boost::this_thread::get_id();
4961                 putLogError(600092, formatter.str(), __FILE__, __LINE__);
4962
4963                 //set last status
4964                 status = FINALIZE;
4965         }
4966
4967         /*-------- DEBUG LOG --------*/
4968         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4969                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4970                                         "handle_sorry_disable(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
4971                 formatter % status % boost::this_thread::get_id();
4972                 putLogDebug(600150, formatter.str(), __FILE__, __LINE__);
4973         }
4974         /*------DEBUG LOG END------*/
4975
4976         return status;
4977 }
4978
4979 //! call from realserver disconnect. use upstream thread and downstream thread
4980 //! @param[in]    upstream and downstream thread id( check! one thread one event )
4981 //! @param[in]    disconnected realserver endpoint.
4982 //! @return     session use EVENT mode
4983 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_disconnect(
4984         const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &rs_endpoint)
4985 {
4986         /*-------- DEBUG LOG --------*/
4987         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4988                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4989                                         "handle_realserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint& rs_endpoint) : "
4990                                         "thread_id = %d, rs_endpoint = [%s]:%d.");
4991                 formatter % thread_id % rs_endpoint.address().to_string() % rs_endpoint.port();
4992                 putLogDebug(600151, formatter.str(), __FILE__, __LINE__);
4993         }
4994         /*------DEBUG LOG END------*/
4995
4996         EVENT_TAG status = FINALIZE;
4997         thread_data_ptr session_data_ptr;
4998
4999         try {
5000                 {
5001                         boost::mutex::scoped_lock sclock(session_thread_data_map_mutex);
5002
5003                         session_thread_data_map_it session_thread_it = session_thread_data_map.find(thread_id);
5004                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
5005                                 boost::format formatter("Invalid thread id. thread id : %d.");
5006                                 formatter % boost::this_thread::get_id();
5007                                 putLogError(600093, formatter.str(), __FILE__, __LINE__);
5008                                 throw - 1;
5009                         }
5010
5011                         session_data_ptr = session_thread_it->second;
5012                 }
5013
5014
5015                 //up thread
5016                 if (session_data_ptr->thread_division == THREAD_DIVISION_UP_STREAM) {
5017                         //end flag is on
5018                         if (session_data_ptr->end_flag == END_FLAG_ON) {
5019                                 //set return status
5020                                 status = CLIENT_RECV;
5021                         }
5022                         //end flag is off
5023                         else {
5024                                 //switch flag is on
5025                                 if (session_data_ptr->switch_flag == SWITCH_FLAG_ON) {
5026                                         //sorry flag is on
5027                                         if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
5028                                                 //set return status
5029                                                 status = SORRYSERVER_SELECT;
5030                                         }
5031                                         //sorry flag is off
5032                                         else {
5033                                                 //set return status
5034                                                 status = REALSERVER_SELECT;
5035                                         }
5036
5037                                         //set switch flag off
5038                                         session_data_ptr->switch_flag = SWITCH_FLAG_OFF;
5039
5040                                         /*-------- DEBUG LOG --------*/
5041                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5042                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5043                                                                         "handle_realserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &"                         "rs_endpoint) : SWITCH_FLAG_OFF. thread id : %d.");
5044                                                 formatter % boost::this_thread::get_id();
5045                                                 putLogDebug(600152, formatter.str(), __FILE__, __LINE__);
5046                                         }
5047                                         /*------DEBUG LOG END------*/
5048                                 }
5049                                 //switch flag is off
5050                                 else {
5051                                         //set return status
5052                                         status = CLIENT_RECV;
5053                                 }
5054                         }
5055                 }
5056                 //down thread
5057                 else {
5058                         //set return status
5059                         status = CLIENT_DISCONNECT;
5060                 }
5061
5062                 //set last status
5063                 session_data_ptr->last_status = status;
5064         } catch (int e) {
5065                 /*-------- DEBUG LOG --------*/
5066                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5067                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5068                                                 "handle_realserver_disconnect() : catch exception e = %d. thread id : %d.");
5069                         formatter % e % boost::this_thread::get_id();
5070                         putLogDebug(600153, formatter.str(), __FILE__, __LINE__);
5071                 }
5072                 /*------DEBUG LOG END------*/
5073
5074                 //set return status
5075                 status = FINALIZE;
5076         } catch (std::exception &ex) {
5077                 std::cerr << "protocol_module_ip::handle_realserver_disconnect() : exception : error = " << ex.what() << "." << std::endl;
5078                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5079                                         "handle_realserver_disconnect() : exception : error = %s. thread id : %d.");
5080                 formatter % ex.what() % boost::this_thread::get_id();
5081                 putLogError(600094, formatter.str(), __FILE__, __LINE__);
5082
5083                 //set return status
5084                 status = FINALIZE;
5085         } catch (...) {
5086                 std::cerr << "protocol_module_ip::handle_realserver_disconnect() : Unknown exception." << std::endl;
5087                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
5088                                         "protocol_module_ip::handle_realserver_disconnect() : "
5089                                         "Unknown exception. thread id : %d.");
5090                 formatter % boost::this_thread::get_id();
5091                 putLogError(600095, formatter.str(), __FILE__, __LINE__);
5092
5093                 //set return status
5094                 status = FINALIZE;
5095         }
5096
5097         /*-------- DEBUG LOG --------*/
5098         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5099                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5100                                         "handle_realserver_disconnect(const boost::thread::id thread_id, "
5101                                         "const boost::asio::ip::tcp::endpoint& rs_endpoint) : return_value = %d. thread id : %d.");
5102                 formatter % status % boost::this_thread::get_id();
5103                 putLogDebug(600154, formatter.str(), __FILE__, __LINE__);
5104         }
5105         /*------DEBUG LOG END------*/
5106
5107         return status;
5108 }
5109
5110 //! call from sorry server disconnect. use upstream thread and downstream thread
5111 //! @param[in]    upstream and downstream thread id( check! one thread one event )
5112 //! @param[in]    disconnect sorryserver endpoint
5113 //! @return        session use EVENT mode
5114 //! @return        session use EVENT mode
5115 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_disconnect(
5116         const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &sorry_endpoint)
5117 {
5118
5119         /*-------- DEBUG LOG --------*/
5120         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5121                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5122                                         "handle_sorryserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint& sorry_endpoint) : "
5123                                         "thread_id = %d, sorry_endpoint = [%s]:%d.");
5124                 formatter % thread_id % sorry_endpoint.address().to_string() % sorry_endpoint.port();
5125                 putLogDebug(600155, formatter.str(), __FILE__, __LINE__);
5126         }
5127         /*------DEBUG LOG END------*/
5128
5129         EVENT_TAG status = FINALIZE;
5130         thread_data_ptr session_data_ptr;
5131
5132         try {
5133                 {
5134                         boost::mutex::scoped_lock sclock(session_thread_data_map_mutex);
5135
5136                         session_thread_data_map_it session_thread_it = session_thread_data_map.find(thread_id);
5137                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
5138                                 boost::format formatter("Invalid thread id. thread id : %d.");
5139                                 formatter % boost::this_thread::get_id();
5140                                 putLogError(600096, formatter.str(), __FILE__, __LINE__);
5141                                 throw - 1;
5142                         }
5143
5144                         session_data_ptr = session_thread_it->second;
5145                 }
5146
5147                 //up thread
5148                 if (session_data_ptr->thread_division == THREAD_DIVISION_UP_STREAM) {
5149                         //end flag is on
5150                         if (session_data_ptr->end_flag == END_FLAG_ON) {
5151                                 //set return status
5152                                 status = CLIENT_RECV;
5153                         }
5154                         //end flag is off
5155                         else {
5156                                 //switch flag is on
5157                                 if (session_data_ptr->switch_flag == SWITCH_FLAG_ON) {
5158                                         //sorry flag is on
5159                                         if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
5160                                                 //set return status
5161                                                 status = SORRYSERVER_SELECT;
5162                                         }
5163                                         //sorry flag is off
5164                                         else {
5165                                                 //set return status
5166                                                 status = REALSERVER_SELECT;
5167                                         }
5168
5169                                         //set switch flag off
5170                                         session_data_ptr->switch_flag = SWITCH_FLAG_OFF;
5171
5172                                         /*-------- DEBUG LOG --------*/
5173                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5174                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5175                                                                         "handle_sorryserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &"                         "sorry_endpoint) : SWITCH_FLAG_OFF. thread id : %d.");
5176                                                 formatter % boost::this_thread::get_id();
5177                                                 putLogDebug(600156, formatter.str(), __FILE__, __LINE__);
5178                                         }
5179                                         /*------DEBUG LOG END------*/
5180
5181                                 }
5182                                 //switch flag is off
5183                                 else {
5184                                         //set return status
5185                                         status = CLIENT_RECV;
5186                                 }
5187                         }
5188                 }
5189                 //down thread
5190                 else {
5191                         //set return status
5192                         status = CLIENT_DISCONNECT;
5193                 }
5194
5195                 //set last status
5196                 session_data_ptr->last_status = status;
5197
5198         } catch (int e) {
5199                 /*-------- DEBUG LOG --------*/
5200                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5201                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5202                                                 "handle_sorryserver_disconnect() : catch exception e = %d. thread id : %d.");
5203                         formatter % e % boost::this_thread::get_id();
5204                         putLogDebug(600157, formatter.str(), __FILE__, __LINE__);
5205                 }
5206                 /*------DEBUG LOG END------*/
5207
5208                 //set return status
5209                 status = FINALIZE;
5210         }
5211
5212         catch (std::exception &ex) {
5213                 std::cerr << "protocol_module_ip::handle_sorryserver_disconnect() : exception : error = " << ex.what() << "." << std::endl;
5214                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5215                                         "handle_sorryserver_disconnect() : exception : error = %s. thread id : %d.");
5216                 formatter % ex.what() % boost::this_thread::get_id();
5217                 putLogError(600097, formatter.str(), __FILE__, __LINE__);
5218
5219                 //set return status
5220                 status = FINALIZE;
5221         } catch (...) {
5222                 std::cerr << "protocol_module_ip::handle_sorryserver_disconnect() : Unknown exception." << std::endl;
5223                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
5224                                         "protocol_module_ip::handle_sorryserver_disconnect() : "
5225                                         "Unknown exception. thread id : %d.");
5226                 formatter % boost::this_thread::get_id();
5227                 putLogError(600098, formatter.str(), __FILE__, __LINE__);
5228
5229                 //set return status
5230                 status = FINALIZE;
5231         }
5232
5233         /*-------- DEBUG LOG --------*/
5234         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5235                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5236                                         "handle_sorryserver_disconnect(const boost::thread::id thread_id, "
5237                                         "const boost::asio::ip::tcp::endpoint& sorry_endpoint) : return_value = %d. thread id : %d.");
5238                 formatter % status % boost::this_thread::get_id();
5239                 putLogDebug(600158, formatter.str(), __FILE__, __LINE__);
5240         }
5241         /*------DEBUG LOG END------*/
5242
5243         return status;
5244 }
5245
5246 //! call from realserver disconnect. use upstream thread and downstream thread.
5247 //! @param[in]    upstream and downstream thread id( check! one thread one event )
5248 //! @param[in]    disconnect realserver endpoint
5249 //! @return        session use EVENT mode.
5250 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_close(
5251         const boost::thread::id thread_id, const boost::asio::ip::udp::endpoint &rs_endpoint)
5252 {
5253         /*-------- DEBUG LOG --------*/
5254         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5255                 boost::format formatter("in/out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5256                                         "handle_realserver_close(const boost::thread::id thread_id, "
5257                                         "boost::asio::ip::udp::endpoint& rs_endpoint) : "
5258                                         "return_value = %d. thread id : %d.");
5259                 formatter % STOP % boost::this_thread::get_id();
5260                 putLogDebug(600159, formatter.str(), __FILE__, __LINE__);
5261         }
5262         /*------DEBUG LOG END------*/
5263
5264         return STOP;
5265 }
5266
5267
5268 bool  protocol_module_ip::get_data_from_recvbuffer(
5269         thread_data_ptr data_ptr, const boost::array<char, MAX_BUFFER_SIZE>& recvbuffer, const size_t recvlen)
5270 {
5271         /*-------- DEBUG LOG --------*/
5272         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5273                 boost::format formatter("in_function : bool protocol_module_ip::get_data_from_recvbuffer("
5274                                         "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5275                                         "const size_t& recvlen) : thread_id = %d.");
5276                 formatter % boost::this_thread::get_id();
5277                 putLogDebug(600160, formatter.str(), __FILE__, __LINE__);
5278         }
5279         /*------DEBUG LOG END------*/
5280
5281         char *tmpbuffer = NULL;
5282
5283         //pointer validate check
5284         if (unlikely(data_ptr == NULL || data_ptr->data_buffer == NULL)) {
5285                 boost::format formatter("Invalid pointer. thread id : %d.");
5286                 formatter % boost::this_thread::get_id();
5287                 putLogError(600099, formatter.str(), __FILE__, __LINE__);
5288
5289                 /*-------- DEBUG LOG --------*/
5290                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5291                         boost::format formatter("out_function : bool protocol_module_ip::get_data_from_recvbuffer("
5292                                                 "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5293                                                 "const size_t& recvlen) : return_value = false. thread id : %d.");
5294                         formatter % boost::this_thread::get_id();
5295                         putLogDebug(600161, formatter.str(), __FILE__, __LINE__);
5296                 }
5297                 /*------DEBUG LOG END------*/
5298
5299                 return false;
5300         }
5301
5302
5303         //the new data can append to buffer directly
5304         if (data_ptr->data_buffer_size - data_ptr->data_length - data_ptr->data_offset >= recvlen) {
5305
5306                 /*-------- DEBUG LOG --------*/
5307                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5308                         std::string datadump;
5309                         dump_memory(recvbuffer.data(), recvlen, datadump);
5310                         boost::format formatter(
5311                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5312                                 "get_data_from_recvbuffer() : before memcpy (data dump) : "
5313                                 "data begin = 0, data_size = %d, data = %s");
5314                         formatter % recvlen % datadump;
5315                         putLogDebug(600162, formatter.str(), __FILE__, __LINE__);
5316                 }
5317                 /*------DEBUG LOG END------*/
5318
5319                 memcpy(data_ptr->data_buffer + data_ptr->data_offset + data_ptr->data_length, recvbuffer.data(), recvlen);
5320
5321                 /*-------- DEBUG LOG --------*/
5322                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5323                         std::string datadump;
5324                         dump_memory(data_ptr->data_buffer + data_ptr->data_offset + data_ptr->data_length, recvlen, datadump);
5325                         boost::format formatter(
5326                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5327                                 "get_data_from_recvbuffer() : after memcpy (data dump) : "
5328                                 "data begin = 0, data_size = %d, data = %s");
5329                         formatter % recvlen % datadump;
5330                         putLogDebug(600163, formatter.str(), __FILE__, __LINE__);
5331                 }
5332                 /*------DEBUG LOG END------*/
5333
5334                 data_ptr->data_length += recvlen;
5335
5336                 /*-------- DEBUG LOG --------*/
5337                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5338                         boost::format formatter("out_function : bool protocol_module_ip::get_data_from_recvbuffer("
5339                                                 "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5340                                                 "const size_t& recvlen) : return_value = true. thread id : %d.");
5341                         formatter % boost::this_thread::get_id();
5342                         putLogDebug(600164, formatter.str(), __FILE__, __LINE__);
5343                 }
5344                 /*------DEBUG LOG END------*/
5345                 return true;
5346         } else {
5347                 //the new data can append to buffer through moving original data
5348                 if (data_ptr->data_buffer_size - data_ptr->data_length >= recvlen) {
5349                         memmove(data_ptr->data_buffer, data_ptr->data_buffer + data_ptr->data_offset, data_ptr->data_length);
5350                         /*-------- DEBUG LOG --------*/
5351                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5352                                 std::string datadump;
5353                                 dump_memory(recvbuffer.data(), recvlen, datadump);
5354                                 boost::format formatter(
5355                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5356                                         "get_data_from_recvbuffer() : before memcpy (data dump) : "
5357                                         "data begin = 0, data_size = %d, data = %s");
5358                                 formatter % recvlen % datadump;
5359                                 putLogDebug(600165, formatter.str(), __FILE__, __LINE__);
5360                         }
5361                         /*------DEBUG LOG END------*/
5362
5363                         memcpy(data_ptr->data_buffer + data_ptr->data_length, recvbuffer.data(), recvlen);
5364
5365                         /*-------- DEBUG LOG --------*/
5366                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5367                                 std::string datadump;
5368                                 dump_memory(data_ptr->data_buffer + data_ptr->data_length, recvlen, datadump);
5369                                 boost::format formatter(
5370                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5371                                         "get_data_from_recvbuffer() : after memcpy (data dump) : "
5372                                         "data begin = 0, data_size = %d, data = %s");
5373                                 formatter % recvlen % datadump;
5374                                 putLogDebug(600166, formatter.str(), __FILE__, __LINE__);
5375                         }
5376                         /*------DEBUG LOG END------*/
5377
5378                         data_ptr->data_offset = 0;
5379                         data_ptr->data_length += recvlen;
5380
5381                         /*-------- DEBUG LOG --------*/
5382                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5383                                 boost::format formatter("out_function : bool protocol_module_ip::get_data_from_recvbuffer("
5384                                                         "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5385                                                         "const size_t& recvlen) : return_value = true. thread id : %d.");
5386                                 formatter % boost::this_thread::get_id();
5387                                 putLogDebug(600167, formatter.str(), __FILE__, __LINE__);
5388                         }
5389                         /*------DEBUG LOG END------*/
5390
5391                         return true;
5392                 } else {
5393                         //not allowed to realloc new buffer who's size is larger than the max size
5394                         if (data_ptr->data_buffer_size >= MAX_IP_MODULE_BUFFER_SIZE
5395                             || data_ptr->data_buffer_size + recvlen >= MAX_IP_MODULE_BUFFER_SIZE) {
5396                                 boost::format formatter("Buffer size is bigger than Max size. thread id : %d.");
5397                                 formatter % boost::this_thread::get_id();
5398                                 putLogError(600100, formatter.str(), __FILE__, __LINE__);
5399
5400                                 /*-------- DEBUG LOG --------*/
5401                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5402                                         boost::format formatter("out_function : bool protocol_module_ip::get_data_from_recvbuffer("
5403                                                                 "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5404                                                                 "const size_t& recvlen) : return_value = false. thread id : %d.");
5405                                         formatter % boost::this_thread::get_id();
5406                                         putLogDebug(600168, formatter.str(), __FILE__, __LINE__);
5407                                 }
5408                                 /*------DEBUG LOG END------*/
5409
5410                                 return false;
5411                         } else {
5412                                 try {
5413                                         /*-------- DEBUG LOG --------*/
5414                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5415                                                 boost::format formatter("new : address = &(%d), size = %lu.");
5416                                                 formatter % static_cast<void *>(tmpbuffer) % MAX_IP_MODULE_BUFFER_SIZE;
5417                                                 putLogDebug(600169, formatter.str(), __FILE__, __LINE__);
5418                                         }
5419                                         /*------DEBUG LOG END------*/
5420
5421                                         //alloc a new buffer who's size is max
5422                                         tmpbuffer = new char[MAX_IP_MODULE_BUFFER_SIZE];
5423                                 } catch (const std::bad_alloc &) { //memory alloc fail
5424                                         std::cerr << "protocol_module_ip::get_data_from_recvbuffer() : exception : Could not allocate memory." << std::endl;
5425                                         boost::format formatter("Could not allocate memory. thread id : %d.");
5426                                         formatter % boost::this_thread::get_id();
5427                                         putLogError(600101, formatter.str(), __FILE__, __LINE__);
5428
5429                                         /*-------- DEBUG LOG --------*/
5430                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5431                                                 boost::format formatter("out_function : bool protocol_module_ip::get_data_from_recvbuffer("
5432                                                                         "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5433                                                                         "const size_t& recvlen) : return_value = false. thread id : %d.");
5434                                                 formatter % boost::this_thread::get_id();
5435                                                 putLogDebug(600170, formatter.str(), __FILE__, __LINE__);
5436                                         }
5437                                         /*------DEBUG LOG END------*/
5438
5439                                         return false;
5440                                 }
5441
5442                                 memset(tmpbuffer, 0, MAX_IP_MODULE_BUFFER_SIZE);
5443
5444                                 /*-------- DEBUG LOG --------*/
5445                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5446                                         std::string datadump;
5447                                         dump_memory(data_ptr->data_buffer + data_ptr->data_offset, data_ptr->data_length, datadump);
5448                                         boost::format formatter(
5449                                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5450                                                 "get_data_from_recvbuffer() : before memcpy (data dump) : "
5451                                                 "data begin = 0, data_size = %d, data = %s");
5452                                         formatter % data_ptr->data_length % datadump;
5453                                         putLogDebug(600171, formatter.str(), __FILE__, __LINE__);
5454                                 }
5455                                 /*------DEBUG LOG END------*/
5456
5457                                 //copy old data to new buffer
5458                                 memcpy(tmpbuffer, data_ptr->data_buffer + data_ptr->data_offset, data_ptr->data_length);
5459
5460                                 /*-------- DEBUG LOG --------*/
5461                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5462                                         std::string datadump;
5463                                         dump_memory(tmpbuffer, data_ptr->data_length, datadump);
5464                                         boost::format formatter(
5465                                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5466                                                 "get_data_from_recvbuffer() : after memcpy (data dump) : "
5467                                                 "data begin = 0, data_size = %d, data = %s");
5468                                         formatter % data_ptr->data_length % datadump;
5469                                         putLogDebug(600172, formatter.str(), __FILE__, __LINE__);
5470                                 }
5471                                 /*------DEBUG LOG END------*/
5472
5473                                 /*-------- DEBUG LOG --------*/
5474                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5475                                         boost::format formatter("delete : address = &(%d).");
5476                                         formatter % static_cast<void *>(data_ptr->data_buffer);
5477                                         putLogDebug(600173, formatter.str(), __FILE__, __LINE__);
5478                                 }
5479                                 /*------DEBUG LOG END------*/
5480
5481                                 //release old memory
5482                                 delete [] data_ptr->data_buffer;
5483                                 data_ptr->data_buffer = tmpbuffer;
5484                                 data_ptr->data_offset = 0;
5485
5486                                 /*-------- DEBUG LOG --------*/
5487                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5488                                         std::string datadump;
5489                                         dump_memory(recvbuffer.data(), recvlen, datadump);
5490                                         boost::format formatter(
5491                                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5492                                                 "get_data_from_recvbuffer() : before memcpy (data dump) : "
5493                                                 "data begin = 0, data_size = %d, data = %s");
5494                                         formatter % recvlen % datadump;
5495                                         putLogDebug(600174, formatter.str(), __FILE__, __LINE__);
5496                                 }
5497                                 /*------DEBUG LOG END------*/
5498
5499                                 //append new data
5500                                 memcpy(data_ptr->data_buffer + data_ptr->data_length, recvbuffer.data(), recvlen);
5501
5502                                 /*-------- DEBUG LOG --------*/
5503                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5504                                         std::string datadump;
5505                                         dump_memory(data_ptr->data_buffer + data_ptr->data_length, recvlen, datadump);
5506                                         boost::format formatter(
5507                                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5508                                                 "get_data_from_recvbuffer() : after memcpy (data dump) : "
5509                                                 "data begin = 0, data_size = %d, data = %s");
5510                                         formatter % recvlen % datadump;
5511                                         putLogDebug(600175, formatter.str(), __FILE__, __LINE__);
5512                                 }
5513                                 /*------DEBUG LOG END------*/
5514
5515                                 data_ptr->data_length += recvlen;
5516                                 data_ptr->data_buffer_size = MAX_IP_MODULE_BUFFER_SIZE ;
5517
5518                                 /*-------- DEBUG LOG --------*/
5519                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5520                                         boost::format formatter("out_function : bool protocol_module_ip::get_data_from_recvbuffer("
5521                                                                 "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5522                                                                 "const size_t& recvlen) : return_value = true. thread id : %d.");
5523                                         formatter % boost::this_thread::get_id();
5524                                         putLogDebug(600176, formatter.str(), __FILE__, __LINE__);
5525                                 }
5526                                 /*------DEBUG LOG END------*/
5527
5528                                 return true;
5529
5530                         }
5531                 }
5532         }
5533 }
5534
5535 bool protocol_module_ip::put_data_into_sendbuffer(
5536         thread_data_ptr data_ptr, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen)
5537 {
5538         /*-------- DEBUG LOG --------*/
5539         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5540                 boost::format formatter("in_function : bool protocol_module_ip::put_data_to_sendbuffer("
5541                                         "thread_data_ptr data_ptr, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
5542                                         "size_t& datalen) : thread_id = %d.");
5543                 formatter % boost::this_thread::get_id();
5544                 putLogDebug(600177, formatter.str(), __FILE__, __LINE__);
5545         }
5546         /*------DEBUG LOG END------*/
5547
5548         size_t sendbuffer_rest_size = 0;
5549         size_t new_offset        = 0;
5550
5551         if (unlikely(data_ptr == NULL || data_ptr->data_buffer == NULL || data_ptr->buffer_sequence.empty())) {
5552                 boost::format formatter("Invalid pointer. thread id : %d.");
5553                 formatter % boost::this_thread::get_id();
5554                 putLogError(600102, formatter.str(), __FILE__, __LINE__);
5555
5556                 /*-------- DEBUG LOG --------*/
5557                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5558                         boost::format formatter("out_function : bool protocol_module_ip::put_data_to_sendbuffer("
5559                                                 "thread_data_ptr data_ptr, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
5560                                                 "size_t& datalen) : return_value = false. thread_id = %d.");
5561                         formatter % boost::this_thread::get_id();
5562                         putLogDebug(600178, formatter.str(), __FILE__, __LINE__);
5563                 }
5564                 /*------DEBUG LOG END------*/
5565
5566                 return false;
5567         }
5568
5569         sendbuffer_rest_size = sendbuffer.size();
5570         datalen = 0;
5571
5572         //buffer_sequence loop
5573         //copy data to send buffer until send buffer is full
5574         while (data_ptr->buffer_sequence.size() > 0) {
5575                 std::pair<char *, size_t> buffer_element = data_ptr->buffer_sequence.front();
5576                 //sendbuffer rest size id bigger than copy possible size
5577                 if (buffer_element.second <= sendbuffer_rest_size) {
5578                         /*-------- DEBUG LOG --------*/
5579                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5580                                 std::string datadump;
5581                                 dump_memory(buffer_element.first, buffer_element.second, datadump);
5582                                 boost::format formatter(
5583                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5584                                         "put_data_to_sendbuffer() : before memcpy (data dump) : "
5585                                         "data begin = 0, data_size = %d, data = %s");
5586                                 formatter % buffer_element.second % datadump;
5587                                 putLogDebug(600179, formatter.str(), __FILE__, __LINE__);
5588                         }
5589                         /*------DEBUG LOG END------*/
5590
5591                         //copy data to send buffer
5592                         memcpy(sendbuffer.c_array() + datalen, buffer_element.first, buffer_element.second);
5593
5594                         /*-------- DEBUG LOG --------*/
5595                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5596                                 std::string datadump;
5597                                 dump_memory(sendbuffer.c_array() + datalen, buffer_element.second, datadump);
5598                                 boost::format formatter(
5599                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5600                                         "put_data_to_sendbuffer() : after memcpy (data dump) : "
5601                                         "data begin = 0, data_size = %d, data = %s");
5602                                 formatter % buffer_element.second % datadump;
5603                                 putLogDebug(600180, formatter.str(), __FILE__, __LINE__);
5604                         }
5605                         /*------DEBUG LOG END------*/
5606
5607                         datalen += buffer_element.second;
5608                         sendbuffer_rest_size -= buffer_element.second;
5609
5610                         //it is the last item of the sequence
5611                         if (data_ptr->buffer_sequence.size() == 1) {
5612                                 //set data position
5613                                 new_offset = buffer_element.first + buffer_element.second - data_ptr->data_buffer;
5614                                 data_ptr->current_message_rest_size -= (new_offset - data_ptr->data_offset);
5615                                 data_ptr->data_length -= (new_offset - data_ptr->data_offset);
5616                                 data_ptr->data_offset = new_offset;
5617                         }
5618
5619
5620                         //delete the item
5621                         data_ptr->buffer_sequence.pop_front();
5622                 }
5623                 //sendbuffer rest size is too small
5624                 else {
5625                         /*-------- DEBUG LOG --------*/
5626                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5627                                 std::string datadump;
5628                                 dump_memory(buffer_element.first, sendbuffer_rest_size, datadump);
5629                                 boost::format formatter(
5630                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5631                                         "put_data_to_sendbuffer() : before memcpy (data dump) : "
5632                                         "data begin = 0, data_size = %d, data = %s");
5633                                 formatter % sendbuffer_rest_size % datadump;
5634                                 putLogDebug(600181, formatter.str(), __FILE__, __LINE__);
5635                         }
5636                         /*------DEBUG LOG END------*/
5637
5638                         //copy data to send buffer
5639                         memcpy(sendbuffer.c_array() + datalen, buffer_element.first, sendbuffer_rest_size);
5640
5641                         /*-------- DEBUG LOG --------*/
5642                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5643                                 std::string datadump;
5644                                 dump_memory(sendbuffer.c_array() + datalen, sendbuffer_rest_size, datadump);
5645                                 boost::format formatter(
5646                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5647                                         "put_data_to_sendbuffer() : after memcpy (data dump) : "
5648                                         "data begin = 0, data_size = %d, data = %s");
5649                                 formatter % sendbuffer_rest_size % datadump;
5650                                 putLogDebug(600182, formatter.str(), __FILE__, __LINE__);
5651                         }
5652                         /*------DEBUG LOG END------*/
5653
5654                         datalen += sendbuffer_rest_size;
5655
5656                         //set item position
5657                         buffer_element.first += sendbuffer_rest_size;
5658                         buffer_element.second -= sendbuffer_rest_size;
5659                         sendbuffer_rest_size = 0;
5660
5661                         //add remain item
5662                         data_ptr->buffer_sequence.push_back(buffer_element);
5663                         //delete the item
5664                         data_ptr->buffer_sequence.pop_front();
5665                         break;
5666                 }
5667         }
5668
5669         /*-------- DEBUG LOG --------*/
5670         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5671                 boost::format formatter("out_function : bool protocol_module_ip::put_data_to_sendbuffer("
5672                                         "thread_data_ptr data_ptr, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
5673                                         "size_t& datalen) : return_value = true. thread_id = %d.");
5674                 formatter % boost::this_thread::get_id();
5675                 putLogDebug(600183, formatter.str(), __FILE__, __LINE__);
5676         }
5677         /*------DEBUG LOG END------*/
5678
5679         return true;
5680 }
5681
5682
5683
5684
5685 //! call from put_data_to_buffer_with_x_forwarded_for(). get x_forwarded_for header's offset and length
5686 //! if the buffer isn't include x_forwarded_for header, create a new one
5687 //! @param[in]    buffer
5688 //! @param[in]    buffer_len
5689 //! @param[out] x_forwarded_for_insert_pos
5690 //! @param[out] x_forwarded_for_context
5691 //! @return  true:create a new x_forwarded_for header
5692 //!         false: edit old one
5693 bool protocol_module_ip::create_x_forwarded_for(const std::string &client_endpoint,
5694                 const char *buffer,
5695                 const size_t buffer_len,
5696                 size_t &x_forwarded_for_insert_pos,
5697                 std::string &x_forwarded_for_context)
5698 {
5699         /*-------- DEBUG LOG --------*/
5700         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5701                 boost::format formatter("in_function : bool protocol_module_ip::create_x_forwarded_for("
5702                                         "const std::string& client_endpoint, const char* buffer, const size_t buffer_len, "
5703                                         "size_t& x_forwarded_for_insert_pos, std::string& x_forwarded_for_context) : thread_id = %d.");
5704                 formatter % boost::this_thread::get_id();
5705                 putLogDebug(600184, formatter.str(), __FILE__, __LINE__);
5706         }
5707         /*------DEBUG LOG END------*/
5708
5709         bool find_ret = false;
5710         size_t x_forwarded_for_offset   = 0;
5711         size_t x_forwarded_for_len    = 0;
5712         size_t http_header_all_offset   = 0;
5713         size_t http_header_all_len    = 0;
5714         const char *X_FORWARDED_FOR    = "X-Forwarded-For";
5715
5716         //search "X-Forwarded-For" header
5717         find_ret = http_utility::find_http_header_x_forwarded_for(buffer, buffer_len,
5718                         x_forwarded_for_offset, x_forwarded_for_len);
5719
5720         /*-------- DEBUG LOG --------*/
5721         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5722                 boost::format formatter("function : bool protocol_module_ip::create_x_forwarded_for() : "
5723                                         "call find_http_header_x_forwarded_for : "
5724                                         "return_value = %d. thread id : %d.");
5725                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
5726                 putLogDebug(600185, formatter.str(), __FILE__, __LINE__);
5727         }
5728         /*------DEBUG LOG END------*/
5729
5730         //search "X-Forwarded-For" result is OK
5731         if (find_ret) {
5732                 //create "X-Forwarded-For" string
5733                 x_forwarded_for_insert_pos = x_forwarded_for_offset + x_forwarded_for_len;
5734                 x_forwarded_for_context = ", ";
5735                 x_forwarded_for_context += client_endpoint;
5736
5737                 /*-------- DEBUG LOG --------*/
5738                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5739                         boost::format formatter("out_function : bool protocol_module_ip::create_x_forwarded_for("
5740                                                 "const std::string& client_endpoint, const char* buffer, const size_t buffer_len, "
5741                                                 "size_t& x_forwarded_for_insert_pos, std::string& x_forwarded_for_context) : return_value = false. thread_id = %d.");
5742                         formatter % boost::this_thread::get_id();
5743                         putLogDebug(600186, formatter.str(), __FILE__, __LINE__);
5744                 }
5745                 /*------DEBUG LOG END------*/
5746
5747                 return false;
5748         }
5749
5750         //create a new one
5751         //because state is HTTP_HEADER, find_http_header_all must be return true
5752         http_utility::find_http_header_all(buffer, buffer_len, http_header_all_offset, http_header_all_len);
5753
5754         /*-------- DEBUG LOG --------*/
5755         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5756                 boost::format formatter("function : bool protocol_module_ip::create_x_forwarded_for() : "
5757                                         "call find_http_header_all : "
5758                                         "return_value = true. thread id : %d.");
5759                 formatter % boost::this_thread::get_id();
5760                 putLogDebug(600187, formatter.str(), __FILE__, __LINE__);
5761         }
5762         /*------DEBUG LOG END------*/
5763
5764         //create "X-Forwarded-For" string
5765         x_forwarded_for_insert_pos = http_header_all_offset;
5766         x_forwarded_for_context = X_FORWARDED_FOR;
5767         x_forwarded_for_context += ": ";
5768         x_forwarded_for_context += client_endpoint;
5769         x_forwarded_for_context += "\r\n";
5770
5771         /*-------- DEBUG LOG --------*/
5772         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5773                 boost::format formatter("out_function : bool protocol_module_ip::create_x_forwarded_for("
5774                                         "const std::string& client_endpoint, const char* buffer, const size_t buffer_len, "
5775                                         "size_t& x_forwarded_for_insert_pos, std::string& x_forwarded_for_context) : return_value = true. thread_id = %d.");
5776                 formatter % boost::this_thread::get_id();
5777                 putLogDebug(600188, formatter.str(), __FILE__, __LINE__);
5778         }
5779         /*------DEBUG LOG END------*/
5780
5781         return true;
5782 }
5783
5784
5785
5786 }//namespace l7vsd
5787
5788 extern "C" l7vs::protocol_module_base*
5789 create_module()
5790 {
5791         return dynamic_cast<l7vs::protocol_module_base *>(new l7vs::protocol_module_ip());
5792 }
5793
5794 extern "C" void
5795 destroy_module(l7vs::protocol_module_base *in)
5796 {
5797         delete in;
5798 }