OSDN Git Service

#535 Fix: change sorry uri regex.
[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 forward_checked = false;
328         bool sorryuri_checked = false;
329         bool stats_checked = false;
330
331         // cf RFC 2396 (A. Collected BNF for URI)
332         sregex    sorry_uri_regex
333         =    +('/' >>
334                *(
335                  alpha | digit |
336                  (set = '-', '_', '.', '!', '~', '*', '\'', '(', ')') |
337                  '%' >> repeat<2>(xdigit) |
338                  (set = ':', '@', '&', '=', '+', '$', ',')
339                )
340                >>
341                *(';' >>
342                  *(
343                    alpha | digit |
344                    (set = '-', '_', '.', '!', '~', '*', '\'', '(', ')') | // mark
345                    '%' >> repeat<2>(xdigit) | // escaped
346                    (set = ':', '@', '&', '=', '+', '$', ',')
347                  ) // pchar
348                ) // param
349              ) // segment
350              >>
351              !('?' >>
352                *(
353                  (set = ';', '/', '?', ':', '@', '&', '=', '+', '$', ',') | //reserved
354                  alpha | digit |
355                  (set = '-', '_', '.', '!', '~', '*', '\'', '(', ')') | // mark
356                  '%' >> repeat<2>(xdigit) // escaped
357                ) // uric
358              ) // query
359              >>
360              !('#' >>
361                *(
362                  (set = ';', '/', '?', ':', '@', '&', '=', '+', '$', ',') | //reserved
363                  alpha | digit |
364                  (set = '-', '_', '.', '!', '~', '*', '\'', '(', ')') | // mark
365                  '%' >> repeat<2>(xdigit) // escaped
366                ) // uric
367              ); // fragment
368
369         typedef std::vector<std::string>::const_iterator vec_str_it;
370
371         try {
372                 vec_str_it it = args.begin();
373                 vec_str_it it_end = args.end();
374                 boost::format formatter;
375
376                 //loop option strings
377                 for (; it != it_end;) {
378                         if (*it == "-T" || *it == "--timeout") {
379                                 // timeout
380                                 if (!timeout_flag) {
381                                         // not set timeout option
382                                         ++it;
383                                         // next parameter exist check
384                                         if (it != it_end) {
385                                                 // next parameter exist
386                                                 if ((*it).substr(0, 1) == "-" || (*it).substr(0, 2) == "--") {
387                                                         continue;
388                                                 }
389
390                                                 try {
391                                                         unsigned long ultimeout = 0;
392                                                         ultimeout = boost::lexical_cast<unsigned long>(*it);
393                                                         // int max value check
394                                                         if (ultimeout > INT_MAX) {
395                                                                 check_result.flag = false;
396                                                                 formatter.parse("'-T/--timeout' option value '%s' is too large.");
397                                                                 formatter % *it;
398                                                                 check_result.message = formatter.str();
399                                                                 putLogError(600000, check_result.message, __FILE__, __LINE__);
400                                                                 break;
401                                                         } else {
402                                                                 timeout_flag = true;
403                                                                 ++it;
404                                                                 continue;
405                                                         }
406                                                 } catch (boost::bad_lexical_cast &e) {
407                                                         // not numeric character
408                                                         check_result.flag = false;
409                                                         formatter.parse("'-T/--timeout' option value '%s' is not numeric character.");
410                                                         formatter % *it;
411                                                         check_result.message = formatter.str();
412                                                         putLogError(600001, check_result.message, __FILE__, __LINE__);
413                                                         break;
414                                                 }
415                                         } else {
416                                                 break;
417                                         }
418                                 } else {
419                                         // already set timeout
420                                         check_result.flag = false;
421                                         check_result.message = "Cannot set multiple option '-T/--timeout'.";
422                                         putLogError(600002, check_result.message, __FILE__, __LINE__);
423                                         break;
424                                 }
425                         } else if (*it == "-R" || *it == "--reschedule") {
426                                 // reschedule
427                                 if (!no_reschedule_flag) {
428                                         // not set no-reschedule flag
429                                         reschedule_flag = true;
430                                 } else {
431                                         // already set no-reschedule flag
432                                         check_result.flag = false;
433                                         check_result.message = "You have to choose either of reschedule or no-reschedule.";
434                                         putLogError(600003, check_result.message, __FILE__, __LINE__);
435                                         break;
436                                 }
437                         } else if (*it == "-N" || *it == "--no-reschedule") {
438                                 // no-reschedule
439                                 if (!reschedule_flag) {
440                                         // not set reschedule flag
441                                         no_reschedule_flag = true;
442                                 } else {
443                                         // already set reschedule flag
444                                         check_result.flag = false;
445                                         check_result.message = "You have to choose either of reschedule or no-reschedule.";
446                                         putLogError(600004, check_result.message, __FILE__, __LINE__);
447                                         break;
448                                 }
449                         }
450                         //option string = "-F"
451                         else if (*it == "-F" || *it == "--forwarded-for") {
452                                 //set forward flag  ON
453                                 forward_checked = true;
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         thread_data_ptr p_up;
1450         thread_data_ptr p_down;
1451         session_thread_data_map_it session_thread_data_it;
1452
1453         //session thread free
1454         try {
1455                 boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
1456
1457                 session_thread_data_it = session_thread_data_map.find(up_thread_id);
1458                 if (session_thread_data_it != session_thread_data_map.end()) {
1459                         p_up = session_thread_data_it->second;
1460                         /*-------- DEBUG LOG --------*/
1461                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1462                                 boost::format formatter("delete : address = &(%d).");
1463                                 formatter % static_cast<void *>(p_up->data_buffer);
1464                                 putLogDebug(600045, formatter.str(), __FILE__, __LINE__);
1465                         }
1466                         /*------DEBUG LOG END------*/
1467
1468                         delete p_up->data_buffer;
1469                         /*-------- DEBUG LOG --------*/
1470                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1471                                 boost::format formatter("delete : address = &(%d).");
1472                                 formatter % static_cast<void *>(p_up.get());
1473                                 putLogDebug(600046, formatter.str(), __FILE__, __LINE__);
1474                         }
1475                         /*------DEBUG LOG END------*/
1476
1477                         session_thread_data_map.erase(up_thread_id);
1478                 }
1479
1480                 session_thread_data_it = session_thread_data_map.find(down_thread_id);
1481                 if (session_thread_data_it != session_thread_data_map.end()) {
1482
1483                         p_down = session_thread_data_it->second;
1484                         /*-------- DEBUG LOG --------*/
1485                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1486                                 boost::format formatter("delete : address = &(%d).");
1487                                 formatter % static_cast<void *>(p_up->data_buffer);
1488                                 putLogDebug(600047, formatter.str(), __FILE__, __LINE__);
1489                         }
1490                         /*------DEBUG LOG END------*/
1491
1492                         delete p_down->data_buffer;
1493                         /*-------- DEBUG LOG --------*/
1494                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1495                                 boost::format formatter("delete : address = &(%d).");
1496                                 formatter % static_cast<void *>(p_down.get());
1497                                 putLogDebug(600048, formatter.str(), __FILE__, __LINE__);
1498                         }
1499                         /*------DEBUG LOG END------*/
1500
1501                         session_thread_data_map.erase(down_thread_id);
1502                 }
1503
1504                 //set return status
1505                 status = STOP;
1506         } catch (const std::exception &ex) {
1507                 std::cerr << "protocol_module_ip::handle_session_finalize() : exception : error = " << ex.what() << "." << std::endl;
1508                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1509                                         "handle_session_finalize() : exception : error = %s. thread id : %d.");
1510                 formatter % ex.what() % boost::this_thread::get_id();
1511                 putLogError(600030, formatter.str(), __FILE__, __LINE__);
1512                 status = STOP;
1513         } catch (...) {
1514                 std::cerr << "protocol_module_ip::handle_session_finalize() : Unknown exception." << std::endl;
1515                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1516                                         "handle_session_finalize() : "
1517                                         "Unknown exception. thread id : %d.");
1518                 formatter % boost::this_thread::get_id();
1519                 putLogError(600031, formatter.str(), __FILE__, __LINE__);
1520                 status = STOP;
1521         }
1522         /*-------- DEBUG LOG --------*/
1523         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1524                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1525                                         "handle_session_finalize(const boost::thread::id up_thread_id, "
1526                                         "const boost::thread::id down_thread_id) : return_value = %d. thread id : %d.");
1527                 formatter % status % boost::this_thread::get_id();
1528                 putLogDebug(600049, formatter.str(), __FILE__, __LINE__);
1529         }
1530         /*------DEBUG LOG END------*/
1531         return status;
1532 }
1533
1534 //! called from after session accept.in client socket use in upstream thread.
1535 //! @param[in]    upstream thread id.
1536 //! @return        session use EVENT mode.
1537 protocol_module_base::EVENT_TAG protocol_module_ip::handle_accept(const boost::thread::id thread_id)
1538 {
1539         /*-------- DEBUG LOG --------*/
1540         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1541                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1542                                         "handle_accept(const boost::thread::id thread_id) : thread_id = %d.");
1543                 formatter % thread_id;
1544                 putLogDebug(600050, formatter.str(), __FILE__, __LINE__);
1545         }
1546         /*------DEBUG LOG END------*/
1547
1548         EVENT_TAG status = FINALIZE;
1549         thread_data_ptr session_data_ptr;
1550         session_thread_data_map_it session_thread_it;
1551
1552         try {
1553                 {
1554                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
1555
1556                         session_thread_it = session_thread_data_map.find(thread_id);
1557                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
1558                                 boost::format formatter("Invalid thread id. thread id : %d.");
1559                                 formatter % boost::this_thread::get_id();
1560                                 putLogError(600032, formatter.str(), __FILE__, __LINE__);
1561                                 throw - 1;
1562                         }
1563
1564                         session_data_ptr = session_thread_it->second;
1565                 }
1566
1567                 //set accept end flag ON
1568                 session_data_ptr->accept_end_flag = ACCEPT_END_FLAG_ON;
1569
1570                 /*-------- DEBUG LOG --------*/
1571                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1572                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1573                                                 "handle_accept(const boost::thread::id thread_id) : ACCEPT_END_FLAG_ON. thread id : %d.");
1574                         formatter % boost::this_thread::get_id();
1575                         putLogDebug(600051, formatter.str(), __FILE__, __LINE__);
1576                 }
1577                 /*------DEBUG LOG END------*/
1578
1579                 //sorry flag on
1580                 if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
1581                         //set return status
1582                         status = SORRYSERVER_SELECT;
1583                 }
1584                 //sorry flag off
1585                 else {
1586                         //set return status
1587                         status = REALSERVER_SELECT;
1588                 }
1589
1590                 //set last status
1591                 session_data_ptr->last_status = status;
1592         } catch (int e) {
1593                 /*-------- DEBUG LOG --------*/
1594                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1595                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1596                                                 "handle_accept() : catch exception e = %d. thread id : %d.");
1597                         formatter % e % boost::this_thread::get_id();
1598                         putLogDebug(600052, formatter.str(), __FILE__, __LINE__);
1599                 }
1600                 /*------DEBUG LOG END------*/
1601                 status = FINALIZE;
1602         } catch (const std::exception &ex) {
1603                 std::cerr << "protocol_module_ip::handle_accept() : exception : error = " << ex.what() << "." << std::endl;
1604                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1605                                         "handle_accept() : exception : error = %s. thread id : %d.");
1606                 formatter % ex.what() % boost::this_thread::get_id();
1607                 putLogError(600033, formatter.str(), __FILE__, __LINE__);
1608                 status = FINALIZE;
1609         } catch (...) {
1610                 std::cerr << "protocol_module_ip::handle_accept() : Unknown exception." << std::endl;
1611                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
1612                                         "protocol_module_ip::handle_accept() : "
1613                                         "Unknown exception. thread id : %d.");
1614                 formatter % boost::this_thread::get_id();
1615                 putLogError(600034, formatter.str(), __FILE__, __LINE__);
1616                 status = FINALIZE;
1617         }
1618
1619         /*-------- DEBUG LOG --------*/
1620         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1621                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1622                                         "handle_accept(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
1623                 formatter % status % boost::this_thread::get_id();
1624                 putLogDebug(600053, formatter.str(), __FILE__, __LINE__);
1625         }
1626         /*------DEBUG LOG END------*/
1627
1628         return status;
1629 }
1630
1631 //! called from after session recv in client socket. use in upstream thread.
1632 //! @param[in]    upstream thread id
1633 //! @param[in]    receive buffer reference.
1634 //! @param[in]    receive length
1635 //! @return        session use EVENT mode.
1636 protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_recv(const boost::thread::id thread_id,
1637                 const boost::array<char, MAX_BUFFER_SIZE>& recvbuffer, const size_t recvlen)
1638 {
1639
1640         /*-------- DEBUG LOG --------*/
1641         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1642                 size_t buffer_size = recvbuffer.size() < recvlen ? recvbuffer.size() : recvlen;
1643                 std::string buffer;
1644                 dump_memory(recvbuffer.data(), buffer_size, buffer);
1645                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1646                                         "handle_client_recv(const boost::thread::id thread_id, "
1647                                         "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
1648                                         "const size_t recvlen) : thread_id = %d, recvbuffer = %s, recvlen = %d.");
1649                 formatter % thread_id % buffer % recvlen;
1650                 putLogDebug(600054, formatter.str(), __FILE__, __LINE__);
1651         }
1652         /*------DEBUG LOG END------*/
1653
1654         EVENT_TAG status                = FINALIZE;
1655         bool find_ret                    = false;
1656         size_t http_header_offset            = 0;
1657         size_t http_header_len                = 0;
1658         size_t http_header_content_length_offset    = 0;
1659         size_t http_header_content_length_len        = 0;
1660         int content_length_value            = 0;
1661         const size_t CR_LF_LEN                = 2; //length of "\r\n"
1662         const size_t CR_LF_CR_LF_LEN            = 4; //length of "\r\n\r\n"
1663         session_thread_data_map_it            session_thread_it;
1664         thread_data_ptr                    session_data_ptr;
1665         http_utility::CHECK_RESULT_TAG             check_ret;
1666
1667         std::string content_length;
1668         cmatch regex_ret;
1669         cregex content_length_regex = icase("Content-Length") >> ":" >> *~_d >> (s1 = +_d) >> *~_d;
1670
1671         //parameter check
1672         if (unlikely(recvlen > recvbuffer.size())) {
1673                 std::cerr << "protocol_module_ip::handle_client_recv() : Data size bigger than buffer size." << std::endl;
1674                 boost::format formatter("Data size bigger than buffer size. thread id : %d.");
1675                 formatter % boost::this_thread::get_id();
1676                 putLogError(600035, formatter.str(), __FILE__, __LINE__);
1677
1678                 /*-------- DEBUG LOG --------*/
1679                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1680                         boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1681                                                 "handle_client_recv(const boost::thread::id thread_id, "
1682                                                 "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
1683                                                 "const size_t recvlen) : return_value = %d. thread id : %d.");
1684                         formatter % FINALIZE % boost::this_thread::get_id();
1685                         putLogDebug(600055, formatter.str(), __FILE__, __LINE__);
1686                 }
1687                 /*------DEBUG LOG END------*/
1688                 return status;
1689         }
1690
1691         try {
1692                 {
1693                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
1694
1695                         session_thread_it = session_thread_data_map.find(thread_id);
1696                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
1697
1698                                 boost::format formatter("Invalid thread id. thread id : %d.");
1699                                 formatter % boost::this_thread::get_id();
1700                                 putLogError(600036, formatter.str(), __FILE__, __LINE__);
1701                                 throw - 1;
1702                         }
1703
1704                         session_data_ptr = session_thread_it->second;
1705                 }
1706
1707                 //end flag on
1708                 if (session_data_ptr->end_flag == END_FLAG_ON) {
1709                         //set return status
1710                         status = CLIENT_RECV;
1711                 }
1712                 //end flag off
1713                 else {
1714                         //copy data from recvbuffer
1715                         if (!get_data_from_recvbuffer(session_data_ptr, recvbuffer, recvlen)) {
1716                                 //copy failed
1717                                 std::cerr << "protocol_module_ip::handle_client_recv() : Data size bigger than buffer size." << std::endl;
1718                                 boost::format formatter("Data size bigger than buffer size. thread id : % id.");
1719                                 formatter % boost::this_thread::get_id();
1720                                 putLogError(600037, formatter.str(), __FILE__, __LINE__);
1721                                 status = FINALIZE;
1722                         } else {
1723                                 if (forwarded_for == FORWARDED_FOR_OFF && session_data_ptr->sorry_flag == SORRY_FLAG_OFF) {
1724                                         session_data_ptr->data_state = UNKNOWN;
1725                                 }
1726                                 //data state is HTTP_START
1727                                 if (session_data_ptr->data_state == HTTP_START) {
1728                                         //search http header
1729                                         find_ret = http_utility::find_http_header_all(session_data_ptr->data_buffer + session_data_ptr->data_offset,
1730                                                         session_data_ptr->data_length,
1731                                                         http_header_offset,
1732                                                         http_header_len
1733                                                                                      );
1734
1735                                         /*-------- DEBUG LOG --------*/
1736                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1737                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1738                                                                         "handle_client_recv() : call find_http_header_all : "
1739                                                                         "return_value = %d. thread id : %d.");
1740                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
1741                                                 putLogDebug(600056, formatter.str(), __FILE__, __LINE__);
1742                                         }
1743                                         /*------DEBUG LOG END------*/
1744
1745                                         //search http header result is NG
1746                                         if (!find_ret) {
1747                                                 //data size bigger than max buffer size
1748                                                 if (session_data_ptr->data_length >= MAX_IP_MODULE_BUFFER_SIZE - recvbuffer.size()) {
1749                                                         //set data state UNKNOWN
1750                                                         session_data_ptr->data_state = UNKNOWN;
1751                                                         //set current message rest size
1752                                                         session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
1753                                                 }
1754                                         }
1755                                         //search http header result is OK
1756                                         else {
1757                                                 //check http method and version
1758                                                 check_ret = http_utility::check_http_method_and_version(session_data_ptr->data_buffer,
1759                                                                 session_data_ptr->data_length);
1760                                                 /*-------- DEBUG LOG --------*/
1761                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1762                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1763                                                                                 "handle_client_recv() : call check_http_method_and_version : "
1764                                                                                 "return_value = %d. thread id : %d.");
1765                                                         formatter % check_ret % boost::this_thread::get_id();
1766                                                         putLogDebug(600057, formatter.str(), __FILE__, __LINE__);
1767                                                 }
1768                                                 /*------DEBUG LOG END------*/
1769
1770                                                 //check http method and version result is NG
1771                                                 if (check_ret == http_utility::CHECK_NG) {
1772                                                         //set data state UNKNOWN
1773                                                         session_data_ptr->data_state = UNKNOWN;
1774                                                         //set current message rest size
1775                                                         session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
1776                                                 }
1777                                                 //check http method and version result is OK
1778                                                 else {
1779                                                         //search Content_Length header
1780                                                         find_ret = http_utility::find_http_header_content_length(session_data_ptr->data_buffer + session_data_ptr->data_offset,
1781                                                                         session_data_ptr->data_length,
1782                                                                         http_header_content_length_offset,
1783                                                                         http_header_content_length_len);
1784                                                         /*-------- DEBUG LOG --------*/
1785                                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1786                                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1787                                                                                         "handle_client_recv() : call find_http_header_content_length : "
1788                                                                                         "return_value = %d. thread id : %d.");
1789                                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
1790                                                                 putLogDebug(600058, formatter.str(), __FILE__, __LINE__);
1791                                                         }
1792                                                         /*------DEBUG LOG END------*/
1793
1794                                                         //search Content_Length result is OK
1795                                                         if (find_ret) {
1796                                                                 //set content length string
1797                                                                 content_length.assign(session_data_ptr->data_buffer + session_data_ptr->data_offset + http_header_content_length_offset,
1798                                                                                       http_header_content_length_len);
1799                                                                 find_ret = regex_search(content_length.c_str(), regex_ret, content_length_regex);
1800
1801                                                                 //"content-length: ddd\r\n"
1802                                                                 if (find_ret) {
1803                                                                         content_length = content_length.substr(
1804                                                                                                  regex_ret.position(1),
1805                                                                                                  regex_ret.length(1));
1806
1807                                                                         //set content length value
1808                                                                         content_length_value = boost::lexical_cast<int>(content_length);
1809                                                                 }
1810
1811                                                                 //http_header context is "\r\n\r\n" only
1812                                                                 if (http_header_len == 0) {
1813                                                                         //set current message rest size
1814                                                                         session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + content_length_value + CR_LF_LEN;
1815                                                                 } else {
1816                                                                         //set current message rest size
1817                                                                         session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + content_length_value + CR_LF_CR_LF_LEN;
1818                                                                 }
1819                                                         }
1820                                                         //search Content_Length result is NG
1821                                                         else {
1822                                                                 //http_header context is "\r\n\r\n" only
1823                                                                 if (http_header_len == 0) {
1824                                                                         //set current message rest size
1825                                                                         session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + CR_LF_LEN;
1826                                                                 } else {
1827                                                                         //set current message rest size
1828                                                                         session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + CR_LF_CR_LF_LEN;
1829                                                                 }
1830
1831                                                         }
1832
1833                                                         //increment http statistics
1834                                                         increment_stats(session_data_ptr->data_buffer + session_data_ptr->data_offset);
1835                                                         /*-------- DEBUG LOG --------*/
1836                                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1837                                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1838                                                                                         "handle_client_recv() : call increment_stats : thread id : %d.");
1839                                                                 formatter % boost::this_thread::get_id();
1840                                                                 putLogDebug(600228, formatter.str(), __FILE__, __LINE__);
1841                                                         }
1842                                                         /*------DEBUG LOG END------*/
1843
1844                                                         //set data state HTTP_HEADER
1845                                                         session_data_ptr->data_state = HTTP_HEADER;
1846
1847                                                 }
1848                                         }
1849                                 }
1850                                 //data state is UNKNOWN
1851                                 else if (session_data_ptr->data_state == UNKNOWN) {
1852                                         //set current message rest size
1853                                         session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
1854                                 } else {
1855                                         //none
1856                                 }
1857
1858                                 //data state is HTTP_START
1859                                 if (session_data_ptr->data_state == HTTP_START) {
1860                                         status = CLIENT_RECV;
1861                                 }
1862                                 //data state is not HTTP_START
1863                                 else {
1864                                         //sorry flag is on
1865                                         if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
1866                                                 //set return status
1867                                                 status = SORRYSERVER_CONNECT;
1868                                         }
1869                                         //sorry flag is off
1870                                         else {
1871                                                 //set return status
1872                                                 status = REALSERVER_CONNECT;
1873                                         }
1874                                 }
1875                         }
1876                 }
1877
1878                 //set last status
1879                 session_data_ptr->last_status = status;
1880         } catch (int e) {
1881                 /*-------- DEBUG LOG --------*/
1882                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1883                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1884                                                 "handle_client_recv() : catch exception e = %d. thread id : %d.");
1885                         formatter % e % boost::this_thread::get_id();
1886                         putLogDebug(600059, formatter.str(), __FILE__, __LINE__);
1887                 }
1888                 /*------DEBUG LOG END------*/
1889                 status = FINALIZE;
1890         } catch (const boost::bad_lexical_cast &) {
1891                 std::cerr << "protocol_module_ip::handle_client_recv() : exception : " <<  "Content_Length field's value is invalid." << std::endl;
1892                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_recv() : "
1893                                         "Content_Length field's value is invalid. thread id : %d.");
1894                 formatter % boost::this_thread::get_id();
1895                 putLogError(600038, formatter.str(), __FILE__, __LINE__);
1896                 status = FINALIZE;
1897         } catch (const std::exception &ex) {
1898                 std::cerr << "protocol_module_ip::handle_client_recv() : exception : error = " << ex.what() << "." << std::endl;
1899                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1900                                         "handle_client_recv() : exception : error = %s. thread id : %d.");
1901                 formatter % ex.what() % boost::this_thread::get_id();
1902                 putLogError(600039, formatter.str(), __FILE__, __LINE__);
1903                 status = FINALIZE;
1904         } catch (...) {
1905                 std::cerr << "protocol_module_ip::handle_client_recv() : Unknown exception." << std::endl;
1906                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
1907                                         "protocol_module_ip::handle_client_recv() : "
1908                                         "Unknown exception. thread id : %d.");
1909                 formatter % boost::this_thread::get_id();
1910                 putLogError(600040, formatter.str(), __FILE__, __LINE__);
1911                 status = FINALIZE;
1912         }
1913
1914         /*-------- DEBUG LOG --------*/
1915         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1916                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1917                                         "handle_client_recv(const boost::thread::id thread_id, "
1918                                         "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
1919                                         "const size_t recvlen) : return_value = %d. thread id : %d.");
1920                 formatter % status % boost::this_thread::get_id();
1921                 putLogDebug(600060, formatter.str(), __FILE__, __LINE__);
1922         }
1923         /*------DEBUG LOG END------*/
1924
1925         return status;
1926 }
1927
1928 //! called from after realserver select.use in upstream thread.
1929 //! @param[in]    upstream thread id
1930 //! @param[out]    realserver TCP endpoint
1931 //! @return        session use EVENT mode.
1932 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_select(
1933         const boost::thread::id thread_id, boost::asio::ip::tcp::endpoint &rs_endpoint)
1934 {
1935
1936         /*-------- DEBUG LOG --------*/
1937         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1938                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1939                                         "handle_realserver_select(const boost::thread::id thread_id, "
1940                                         "boost::asio::ip::tcp::endpoint& rs_endpoint) : "
1941                                         "thread_id = %d, rs_endpoint = [%s]:%d.");
1942                 formatter % thread_id % rs_endpoint.address().to_string() % rs_endpoint.port();
1943                 putLogDebug(600061, formatter.str(), __FILE__, __LINE__);
1944         }
1945         /*------DEBUG LOG END------*/
1946
1947         EVENT_TAG status = FINALIZE;
1948         boost::asio::ip::tcp::endpoint init_endpoint;
1949         thread_data_ptr session_data_ptr;
1950         session_thread_data_map_it session_thread_it;
1951         session_thread_data_map_it session_thread_it_end;
1952         realserverlist_type::iterator    rs_list_itr;
1953
1954         if (unlikely(schedule_tcp.empty())) {
1955                 std::cerr << "protocol_module_ip::handle_realserver_select() : Schedule_tcp function is empty." << std::endl;
1956                 boost::format formatter("Schedule_tcp function is empty. thread id : %d.");
1957                 formatter % boost::this_thread::get_id();
1958                 putLogError(600041, formatter.str(), __FILE__, __LINE__);
1959
1960                 /*-------- DEBUG LOG --------*/
1961                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1962                         boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1963                                                 "handle_realserver_select(const boost::thread::id thread_id, "
1964                                                 "boost::asio::ip::tcp::endpoint& rs_endpoint)"
1965                                                 " : return_value = %d. thread id : %d.");
1966                         formatter % FINALIZE % boost::this_thread::get_id();
1967                         putLogDebug(600062, formatter.str(), __FILE__, __LINE__);
1968                 }
1969                 /*------DEBUG LOG END------*/
1970                 return FINALIZE;
1971         }
1972
1973
1974         try {
1975                 {
1976                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
1977
1978                         session_thread_it = session_thread_data_map.find(thread_id);
1979                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
1980                                 boost::format formatter("Invalid thread id. thread id : %d.");
1981                                 formatter % boost::this_thread::get_id();
1982                                 putLogError(600042, formatter.str(), __FILE__, __LINE__);
1983                                 throw - 1;
1984                         }
1985
1986                         session_data_ptr = session_thread_it->second;
1987                 }
1988
1989                 //initialize realserver endpoint
1990                 rs_endpoint = init_endpoint;
1991
1992                 boost::mutex::scoped_lock lock(session_data_mutex);
1993
1994                 //get endpoint data from the ip data
1995                 int ret = ip_data_processor->get_endpoint_from_session_data(session_data_ptr->ip_hash,
1996                                 rs_endpoint);
1997
1998                 /*-------- DEBUG LOG --------*/
1999                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2000                         boost::format formatter("function : protocol_module_base::EVENT_TAG "
2001                                                 "protocol_module_ip::handle_realserver_select() : "
2002                                                 "get_endpoint_from_session_data() end. thread id : %d.");
2003                         formatter % boost::this_thread::get_id();
2004                         putLogDebug(600063, formatter.str(), __FILE__, __LINE__);
2005                 }
2006                 /*------DEBUG LOG END------*/
2007
2008                 //endpoint is matched
2009                 if (ret == 0) {
2010                         int is_match = 0;
2011                         //find the rs_endpoint in rs_list
2012                         {
2013                                 rs_list_scoped_lock scoped_lock(rs_list_lock, rs_list_unlock);
2014
2015                                 rs_list_itr = rs_list_begin();
2016
2017                                 while (rs_list_itr != rs_list_end()) {
2018
2019                                         if (rs_list_itr->tcp_endpoint == rs_endpoint) {
2020                                                 if (rs_list_itr->weight != 0) {
2021                                                         is_match = 1;
2022                                                 }
2023                                                 break;
2024                                         }
2025
2026                                         rs_list_itr = rs_list_next(rs_list_itr);
2027                                 }
2028                         }
2029
2030                         //endpoint is matched in the list
2031                         if (is_match) {
2032                                 //set return status
2033                                 status = REALSERVER_CONNECT;
2034                         }
2035                         //endpoint is not matched in the list
2036                         else {
2037                                 //if reschedule is on then try multi times connect
2038                                 if (reschedule == 1) {
2039                                         // init rs_endpoint
2040                                         rs_endpoint = init_endpoint;
2041                                         {
2042                                                 rs_list_scoped_lock scoped_lock(rs_list_lock, rs_list_unlock);
2043                                                 schedule_tcp(thread_id, rs_list_begin, rs_list_end, rs_list_next, rs_endpoint);
2044                                         }
2045
2046                                         /*-------- DEBUG LOG --------*/
2047                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2048                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2049                                                                         "handle_realserver_select() : call schedule_tcp : "
2050                                                                         "rs_endpoint = [%s]:%d. thread id : %d.");
2051                                                 formatter % rs_endpoint.address().to_string() % rs_endpoint.port() % boost::this_thread::get_id();
2052                                                 putLogDebug(600064, formatter.str(), __FILE__, __LINE__);
2053                                         }
2054                                         /*------DEBUG LOG END------*/
2055
2056                                         //get the endpoint by schedule successfully
2057                                         if (init_endpoint != rs_endpoint) {
2058                                                 time_t init_time = 0;
2059
2060                                                 //write data to session table
2061                                                 ip_data_processor->write_session_data(session_data_ptr->ip_hash, rs_endpoint, init_time);
2062                                                 /*-------- DEBUG LOG --------*/
2063                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2064                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG "
2065                                                                                 "protocol_module_ip::handle_realserver_select() : "
2066                                                                                 "write_session_data() end. thread id : %d.");
2067                                                         formatter % boost::this_thread::get_id();
2068                                                         putLogDebug(600065, formatter.str(), __FILE__, __LINE__);
2069                                                 }
2070                                                 /*------DEBUG LOG END------*/
2071
2072                                                 //set return status
2073                                                 status = REALSERVER_CONNECT;
2074                                         }
2075                                         //get the endpoint by schedule unsuccessfully
2076                                         else {
2077                                                 session_data_ptr->sorry_flag = SORRY_FLAG_ON;
2078                                                 /*-------- DEBUG LOG --------*/
2079                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2080                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2081                                                                                 "handle_realserver_select()"
2082                                                                                 " : SORRY_FLAG_ON. thread id : %d.");
2083                                                         formatter % boost::this_thread::get_id();
2084                                                         putLogDebug(600066, formatter.str(), __FILE__, __LINE__);
2085                                                 }
2086                                                 /*------DEBUG LOG END------*/
2087
2088                                                 //set return status
2089                                                 status = SORRYSERVER_SELECT;
2090                                         }
2091                                 }
2092                                 //reschedule is off
2093                                 else {
2094                                         //set return status
2095                                         status = CLIENT_DISCONNECT;
2096                                 }
2097                         }
2098                 }
2099                 //endpoint is not matched
2100                 else {
2101                         // init rs_endpoint
2102                         rs_endpoint = init_endpoint;
2103
2104                         //call schedule_module's schedule function, get realserver endpoint
2105                         {
2106                                 rs_list_scoped_lock scoped_lock(rs_list_lock, rs_list_unlock);
2107                                 schedule_tcp(thread_id, rs_list_begin, rs_list_end, rs_list_next, rs_endpoint);
2108                         }
2109
2110                         /*-------- DEBUG LOG --------*/
2111                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2112                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2113                                                         "handle_realserver_select() : call schedule_tcp : "
2114                                                         "rs_endpoint = [%s]:%d. thread id : %d.");
2115                                 formatter % rs_endpoint.address().to_string() % rs_endpoint.port() % boost::this_thread::get_id();
2116                                 putLogDebug(600067, formatter.str(), __FILE__, __LINE__);
2117                         }
2118                         /*------DEBUG LOG END------*/
2119
2120                         //get the endpoint by schedule successfully
2121                         if (init_endpoint != rs_endpoint) {
2122                                 time_t init_time = 0;
2123
2124                                 //write data to session table
2125                                 ip_data_processor->write_session_data(session_data_ptr->ip_hash, rs_endpoint, init_time);
2126                                 /*-------- DEBUG LOG --------*/
2127                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2128                                         boost::format formatter("function : protocol_module_base::EVENT_TAG "
2129                                                                 "protocol_module_ip::handle_realserver_select() : "
2130                                                                 "write_session_data() end. thread id : %d.");
2131                                         formatter % boost::this_thread::get_id();
2132                                         putLogDebug(600068, formatter.str(), __FILE__, __LINE__);
2133                                 }
2134                                 /*------DEBUG LOG END------*/
2135
2136                                 //set return status
2137                                 status = REALSERVER_CONNECT;
2138                         }
2139                         //get the endpoint by schedule unsuccessfully
2140                         else {
2141                                 session_data_ptr->sorry_flag = SORRY_FLAG_ON;
2142                                 /*-------- DEBUG LOG --------*/
2143                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2144                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2145                                                                 "handle_realserver_select()"
2146                                                                 " : SORRY_FLAG_ON. thread id : %d.");
2147                                         formatter % boost::this_thread::get_id();
2148                                         putLogDebug(600069, formatter.str(), __FILE__, __LINE__);
2149                                 }
2150                                 /*------DEBUG LOG END------*/
2151                                 //set return status
2152                                 status = SORRYSERVER_SELECT;
2153
2154                         }
2155                 }
2156
2157                 //set last status
2158                 session_data_ptr->last_status = status;
2159         } catch (int e) {
2160                 /*-------- DEBUG LOG --------*/
2161                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2162                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2163                                                 "handle_realserver_select() : catch exception e = %d. thread id : %d.");
2164                         formatter % e % boost::this_thread::get_id();
2165                         putLogDebug(600070, formatter.str(), __FILE__, __LINE__);
2166                 }
2167                 /*------DEBUG LOG END------*/
2168                 status = FINALIZE;
2169         } catch (const std::exception &ex) {
2170                 std::cerr << "protocol_module_ip::handle_realserver_select() : exception : error = " << ex.what() << "." << std::endl;
2171                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2172                                         "handle_realserver_select() : exception : error = %s. thread id : %d.");
2173                 formatter % ex.what() % boost::this_thread::get_id();
2174                 putLogError(600043, formatter.str(), __FILE__, __LINE__);
2175                 status = FINALIZE;
2176         } catch (...) {
2177                 std::cerr << "protocol_module_ip::handle_realserver_select() : Unknown exception." << std::endl;
2178                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
2179                                         "protocol_module_ip::handle_realserver_select() : "
2180                                         "Unknown exception. thread id : %d.");
2181                 formatter % boost::this_thread::get_id();
2182                 putLogError(600044, formatter.str(), __FILE__, __LINE__);
2183                 status = FINALIZE;
2184         }
2185
2186         /*-------- DEBUG LOG --------*/
2187         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2188                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2189                                         "handle_realserver_select(const boost::thread::id thread_id, "
2190                                         "boost::asio::ip::tcp::endpoint& rs_endpoint)"
2191                                         " : return_value = %d. thread id : %d.");
2192                 formatter % status % boost::this_thread::get_id();
2193                 putLogDebug(600071, formatter.str(), __FILE__, __LINE__);
2194         }
2195         /*------DEBUG LOG END------*/
2196         return status;
2197 }
2198
2199 //! called from after realserver select
2200 //! @param[in]    upstream thread id
2201 //! @param[out]    realserver UDP endpoint
2202 //! @param[out]    send buffer reference
2203 //! @param[out]    send data length
2204 //! @return        session use EVENT mode.
2205 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_select(
2206         const boost::thread::id thread_id, boost::asio::ip::udp::endpoint &rs_endpoint, boost::array < char,
2207         MAX_BUFFER_SIZE > & sendbuffer, size_t &datalen)
2208 {
2209         /*-------- DEBUG LOG --------*/
2210         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2211                 boost::format formatter("in/out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2212                                         "handle_realserver_select(const boost::thread::id thread_id, "
2213                                         "boost::asio::ip::udp::endpoint& rs_endpoint, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
2214                                         "size_t& datalen) : "
2215                                         "return_value = %d. thread id : %d.");
2216                 formatter % STOP % boost::this_thread::get_id();
2217                 putLogDebug(600072, formatter.str(), __FILE__, __LINE__);
2218         }
2219         /*------DEBUG LOG END------*/
2220         return STOP;
2221 }
2222 //! called from after realserver connect
2223 //! @param[in]    upstream thread id
2224 //! @param[out]    sendbuffer reference
2225 //! @param[out]    send data length
2226 //! @return        session use EVENT mode.
2227 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_connect(
2228         const boost::thread::id thread_id, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen)
2229 {
2230         /*-------- DEBUG LOG --------*/
2231         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2232                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2233                                         "handle_realserver_connect(const boost::thread::id thread_id, "
2234                                         "boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t& datalen) : "
2235                                         "thread_id = %d.");
2236                 formatter % thread_id;
2237                 putLogDebug(600073, formatter.str(), __FILE__, __LINE__);
2238         }
2239         /*------DEBUG LOG END------*/
2240
2241         EVENT_TAG status            = FINALIZE;
2242         size_t send_possible_size        = 0;
2243         size_t x_forwarded_for_insert_pos   = 0;
2244         thread_data_ptr                session_data_ptr;
2245         session_thread_data_map_it        session_thread_it;
2246         std::pair<char *, size_t>        buffer_element;
2247         std::string                x_forwarded_for_context;
2248
2249         try {
2250                 {
2251                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
2252
2253                         //thread id check
2254                         session_thread_it = session_thread_data_map.find(thread_id);
2255                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
2256                                 boost::format formatter("Invalid thread id. thread id : %d.");
2257                                 formatter % boost::this_thread::get_id();
2258                                 putLogError(600045, formatter.str(), __FILE__, __LINE__);
2259                                 throw - 1;
2260                         }
2261
2262                         session_data_ptr = session_thread_it->second;
2263                 }
2264
2265                 send_possible_size = std::min(session_data_ptr->current_message_rest_size,
2266                                               session_data_ptr->data_length
2267                                              );
2268
2269                 //buffer sequence is empty
2270                 if (session_data_ptr->buffer_sequence.empty()) {
2271                         //data state is HTTP_HEADER
2272                         if (session_data_ptr->data_state == HTTP_HEADER) {
2273                                 //forwarded_for flag is on
2274                                 if (forwarded_for == FORWARDED_FOR_ON) {
2275                                         //search X-Forwarded-For header
2276                                         create_x_forwarded_for(session_data_ptr->client_endpoint.address().to_string(),
2277                                                                session_data_ptr->data_buffer + session_data_ptr->data_offset,
2278                                                                session_data_ptr->data_length,
2279                                                                x_forwarded_for_insert_pos,
2280                                                                x_forwarded_for_context);
2281
2282                                         //put buffer data to buffer_sequence
2283                                         buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset;
2284                                         buffer_element.second = x_forwarded_for_insert_pos;
2285                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2286
2287                                         session_data_ptr->forwarded_for_buffer.assign(0);
2288
2289                                         /*-------- DEBUG LOG --------*/
2290                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2291                                                 std::string datadump;
2292                                                 dump_memory(x_forwarded_for_context.c_str(),
2293                                                             x_forwarded_for_context.size(), datadump);
2294                                                 boost::format formatter(
2295                                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2296                                                         "handle_realserver_connect() : before memcpy (data dump) : "
2297                                                         "data begin = 0, data_size = %d, data = %s");
2298                                                 formatter %  x_forwarded_for_context.size() % datadump;
2299                                                 putLogDebug(600074, formatter.str(), __FILE__, __LINE__);
2300                                         }
2301                                         /*------DEBUG LOG END------*/
2302
2303                                         memcpy(session_data_ptr->forwarded_for_buffer.data(),
2304                                                x_forwarded_for_context.c_str(),
2305                                                x_forwarded_for_context.size());
2306
2307                                         /*-------- DEBUG LOG --------*/
2308                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2309                                                 std::string datadump;
2310                                                 dump_memory(x_forwarded_for_context.c_str(),
2311                                                             x_forwarded_for_context.size(), datadump);
2312                                                 boost::format formatter(
2313                                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2314                                                         "handle_realserver_connect() : after memcpy (data dump) : "
2315                                                         "data begin = 0, data_size = %d, data = %s");
2316                                                 formatter % x_forwarded_for_context.size() % datadump;
2317                                                 putLogDebug(600075, formatter.str(), __FILE__, __LINE__);
2318                                         }
2319                                         /*------DEBUG LOG END------*/
2320
2321                                         //set buffer's position
2322                                         buffer_element.first = session_data_ptr->forwarded_for_buffer.data();
2323                                         buffer_element.second = x_forwarded_for_context.size();
2324
2325                                         //set data to buffer_sequence
2326                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2327
2328                                         //set buffer's position
2329                                         buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset + x_forwarded_for_insert_pos;
2330                                         buffer_element.second = send_possible_size - x_forwarded_for_insert_pos;
2331
2332                                         //set data to buffer_sequence
2333                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2334                                 }
2335                                 //forwarded_for flag is off
2336                                 else {
2337                                         //set buffer's position
2338                                         buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset;
2339                                         buffer_element.second = send_possible_size;
2340
2341                                         //set data to buffer_sequence
2342                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2343                                 }
2344                                 session_data_ptr->data_state = HTTP_BODY;
2345                         }
2346                         //data state is not HTTP_HEADER
2347                         else {
2348
2349                                 buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset;
2350                                 buffer_element.second = send_possible_size;
2351
2352                                 //set data to buffer_sequence
2353                                 session_data_ptr->buffer_sequence.push_back(buffer_element);
2354
2355                         }
2356                 }
2357
2358                 //put buffer_sequence data into sendbuffer
2359                 put_data_into_sendbuffer(session_data_ptr, sendbuffer, datalen);
2360
2361                 //set return status
2362                 status = REALSERVER_SEND;
2363
2364                 //set last status
2365                 session_data_ptr->last_status = status;
2366         } catch (int e) {
2367                 /*-------- DEBUG LOG --------*/
2368                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2369                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2370                                                 "handle_realserver_connect() : catch exception e = %d. thread id : %d.");
2371                         formatter % e % boost::this_thread::get_id();
2372                         putLogDebug(600076, formatter.str(), __FILE__, __LINE__);
2373                 }
2374                 /*------DEBUG LOG END------*/
2375
2376                 //set return status
2377                 status = FINALIZE;
2378         } catch (std::exception &ex) {
2379                 std::cerr << "protocol_module_ip::handle_realserver_connect() : exception : error = " << ex.what() << "." << std::endl;
2380                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2381                                         "handle_realserver_connect() : exception : error = %s. thread id : %d.");
2382                 formatter % ex.what() % boost::this_thread::get_id();
2383                 putLogError(600046, formatter.str(), __FILE__, __LINE__);
2384
2385                 //set return status
2386                 status = FINALIZE;
2387         } catch (...) {
2388                 std::cerr << "protocol_module_ip::handle_realserver_connect() : Unknown exception." << std::endl;
2389                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2390                                         "handle_realserver_connect() : Unknown exception. thread id : %d.");
2391                 formatter % boost::this_thread::get_id();
2392                 putLogError(600047, formatter.str(), __FILE__, __LINE__);
2393
2394                 //set return status
2395                 status = FINALIZE;
2396         }
2397
2398         /*-------- DEBUG LOG --------*/
2399         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2400                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2401                                         "handle_realserver_connect(const boost::thread::id thread_id, "
2402                                         "boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
2403                                         "size_t& datalen) : return_value = %d. thread id : %d.");
2404                 formatter % status % boost::this_thread::get_id();
2405                 putLogDebug(600077, formatter.str(), __FILE__, __LINE__);
2406         }
2407         /*------DEBUG LOG END------*/
2408
2409         return status;
2410 }
2411
2412 //! called from after realserver connection fail
2413 //! @param[in]    upstream thread id
2414 //! @param[in]    fail realserver endpoint reference
2415 //! @return        session use EVENT mode.
2416 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_connection_fail(
2417         const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &rs_endpoint)
2418 {
2419         /*-------- DEBUG LOG --------*/
2420         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2421                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2422                                         "handle_realserver_connection_fail(const boost::thread::id thread_id, "
2423                                         "const boost::asio::ip::tcp::endpoint& rs_endpoint) : "
2424                                         "thread_id = %d, rs_endpoint = [%s]:%d.");
2425                 formatter % thread_id % rs_endpoint.address().to_string() % rs_endpoint.port();
2426                 putLogDebug(600078, formatter.str(), __FILE__, __LINE__);
2427         }
2428         /*------DEBUG LOG END------*/
2429
2430         EVENT_TAG status = FINALIZE;
2431         thread_data_ptr session_data_ptr;
2432         session_thread_data_map_it session_thread_it;
2433
2434         try {
2435                 boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
2436
2437                 session_thread_it = session_thread_data_map.find(thread_id);
2438                 if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
2439                         boost::format formatter("Invalid thread id. thread id : %d.");
2440                         formatter % boost::this_thread::get_id();
2441                         putLogError(600048, formatter.str(), __FILE__, __LINE__);
2442                         throw - 1;
2443                 }
2444
2445                 session_data_ptr = session_thread_it->second;
2446
2447                 //set return status
2448                 status = CLIENT_DISCONNECT;
2449
2450                 //set last status
2451                 session_data_ptr->last_status = status;
2452         } catch (int e) {
2453                 /*-------- DEBUG LOG --------*/
2454                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2455                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2456                                                 "handle_realserver_connection_fail() : catch exception e = %d. thread id : %d.");
2457                         formatter % e % boost::this_thread::get_id();
2458                         putLogDebug(600079, formatter.str(), __FILE__, __LINE__);
2459                 }
2460                 /*------DEBUG LOG END------*/
2461
2462                 //set return status
2463                 status = FINALIZE;
2464         } catch (const std::exception &ex) {
2465                 std::cerr << "protocol_module_ip::handle_realserver_connection_fail() : exception : error = " << ex.what() << "." << std::endl;
2466                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2467                                         "handle_realserver_connection_fail() : exception : error = %s. thread id : %d.");
2468                 formatter % ex.what() % boost::this_thread::get_id();
2469                 putLogError(600049, formatter.str(), __FILE__, __LINE__);
2470
2471                 //set return status
2472                 status = FINALIZE;
2473         } catch (...) {
2474                 std::cerr << "protocol_module_ip::handle_realserver_connection_fail() : Unknown exception." << std::endl;
2475                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
2476                                         "protocol_module_ip::handle_realserver_connection_fail() : "
2477                                         "Unknown exception. thread id : %d.");
2478                 formatter % boost::this_thread::get_id();
2479                 putLogError(600050, formatter.str(), __FILE__, __LINE__);
2480
2481                 //set return status
2482                 status = FINALIZE;
2483         }
2484
2485         /*-------- DEBUG LOG --------*/
2486         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2487                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2488                                         "handle_realserver_connection_fail(const boost::thread::id thread_id, "
2489                                         "const boost::asio::ip::tcp::endpoint& rs_endpoint) : return_value = %d. thread id : %d.");
2490                 formatter % status % boost::this_thread::get_id();
2491                 putLogDebug(600080, formatter.str(), __FILE__, __LINE__);
2492         }
2493         /*------DEBUG LOG END------*/
2494
2495         return status;
2496 }
2497 //! called from after realserver send.
2498 //! @param[in]    upstream thread id
2499 //! @return        session use EVENT mode.
2500 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_send(
2501         const boost::thread::id thread_id)
2502 {
2503         /*-------- DEBUG LOG --------*/
2504         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2505                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2506                                         "handle_realserver_send(const boost::thread::id thread_id) : thread_id = %d.");
2507                 formatter % thread_id;
2508                 putLogDebug(600081, formatter.str(), __FILE__, __LINE__);
2509         }
2510         /*------DEBUG LOG END------*/
2511
2512         EVENT_TAG status                = FINALIZE;
2513         size_t http_header_all_offset            = 0;
2514         size_t http_header_all_len            = 0;
2515         size_t http_header_content_length_offset    = 0;
2516         size_t http_header_content_length_len        = 0;
2517         const size_t CR_LF_LEN                = 2;
2518         const size_t CR_LF_CR_LF_LEN            = 4;
2519         int content_length_value            = 0;
2520
2521         std::string content_length;
2522         cmatch regex_ret;
2523         cregex content_length_regex = icase("Content-Length") >> ":" >> *~_d >> (s1 = +_d) >> *~_d;
2524
2525
2526         bool find_ret = false;
2527         http_utility::CHECK_RESULT_TAG check_ret;
2528
2529         thread_data_ptr session_data_ptr;
2530         session_thread_data_map_it session_thread_it;
2531
2532         try {
2533                 {
2534                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
2535
2536                         //thread id check
2537                         session_thread_it = session_thread_data_map.find(thread_id);
2538                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
2539                                 boost::format formatter("Invalid thread id. thread id : %d.");
2540                                 formatter % boost::this_thread::get_id();
2541                                 putLogError(600051, formatter.str(), __FILE__, __LINE__);
2542                                 throw - 1;
2543                         }
2544
2545                         session_data_ptr = session_thread_it->second;
2546                 }
2547
2548                 //current_message_rest_size > 0
2549                 if (session_data_ptr->current_message_rest_size > 0) {
2550                         //data size > 0
2551                         if (session_data_ptr->data_length > 0) {
2552                                 //set return status
2553                                 status = REALSERVER_CONNECT;
2554                         }
2555                         //data size is 0
2556                         else {
2557                                 //data offset is 0
2558                                 session_data_ptr->data_offset = 0;
2559
2560                                 //set return status
2561                                 status = CLIENT_RECV;
2562                         }
2563                 }
2564                 //current_message_rest_size is 0
2565                 else {
2566                         //data size > 0
2567                         if (session_data_ptr->data_length > 0) {
2568                                 //data state is HTTP_BODY
2569                                 if (session_data_ptr->data_state == HTTP_BODY) {
2570                                         //search whole http header, get whole http header's offset and length
2571                                         find_ret = http_utility::find_http_header_all(session_data_ptr->data_buffer + session_data_ptr->data_offset,
2572                                                         session_data_ptr->data_length,
2573                                                         http_header_all_offset,
2574                                                         http_header_all_len
2575                                                                                      );
2576
2577                                         /*-------- DEBUG LOG --------*/
2578                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2579                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2580                                                                         "handle_realserver_send() : call find_http_header_all : "
2581                                                                         "return_value = %d. thread id : %d.");
2582                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
2583                                                 putLogDebug(600082, formatter.str(), __FILE__, __LINE__);
2584                                         }
2585                                         /*------DEBUG LOG END------*/
2586
2587                                         //search http header result is NG
2588                                         if (!find_ret) {
2589                                                 //set data state HTTP_START
2590                                                 session_data_ptr->data_state = HTTP_START;
2591
2592                                                 //set return status
2593                                                 status = CLIENT_RECV;
2594                                         }
2595                                         //search http header result is OK
2596                                         else {
2597                                                 //check http method and version
2598                                                 check_ret = http_utility::check_http_method_and_version(session_data_ptr->data_buffer + session_data_ptr->data_offset,
2599                                                                 session_data_ptr->data_length);
2600
2601                                                 /*-------- DEBUG LOG --------*/
2602                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2603                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2604                                                                                 "handle_realserver_send() : call check_http_method_and_version : "
2605                                                                                 "return_value = %d. thread id : %d.");
2606                                                         formatter % check_ret % boost::this_thread::get_id();
2607                                                         putLogDebug(600083, formatter.str(), __FILE__, __LINE__);
2608                                                 }
2609                                                 /*------DEBUG LOG END------*/
2610
2611                                                 //check method and version result is NG
2612                                                 if (check_ret == http_utility::CHECK_NG) {
2613                                                         //set current message rest size
2614                                                         session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
2615
2616                                                         //set data state UNKNOWN
2617                                                         session_data_ptr->data_state = UNKNOWN;
2618                                                 }
2619                                                 //check method and version result is OK
2620                                                 else {
2621                                                         //search Content_Length header
2622                                                         find_ret = http_utility::find_http_header_content_length(session_data_ptr->data_buffer + session_data_ptr->data_offset,
2623                                                                         session_data_ptr->data_length,
2624                                                                         http_header_content_length_offset,
2625                                                                         http_header_content_length_len);
2626
2627                                                         /*-------- DEBUG LOG --------*/
2628                                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2629                                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2630                                                                                         "handle_realserver_send() : call find_http_header_content_length : "
2631                                                                                         "return_value = %d. thread id : %d.");
2632                                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
2633                                                                 putLogDebug(600084, formatter.str(), __FILE__, __LINE__);
2634                                                         }
2635                                                         /*------DEBUG LOG END------*/
2636
2637                                                         //search Content_Length result is OK
2638                                                         if (find_ret) {
2639                                                                 content_length.assign(session_data_ptr->data_buffer + session_data_ptr->data_offset + http_header_content_length_offset,
2640                                                                                       http_header_content_length_len);
2641                                                                 find_ret = regex_search(content_length.c_str(), regex_ret, content_length_regex);
2642
2643                                                                 //"content-length: ddd\r\n"
2644                                                                 if (find_ret) {
2645                                                                         content_length = content_length.substr(
2646                                                                                                  regex_ret.position(1),
2647                                                                                                  regex_ret.length(1));
2648
2649                                                                         //set content length value
2650                                                                         content_length_value = boost::lexical_cast<int>(content_length);
2651                                                                 }
2652
2653                                                                 //http_header context is "\r\n\r\n" only
2654                                                                 if (http_header_all_len == 0) {
2655                                                                         //set current message rest size
2656                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + content_length_value + CR_LF_LEN;
2657                                                                 } else {
2658                                                                         //set current message rest size
2659                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + content_length_value + CR_LF_CR_LF_LEN;
2660                                                                 }
2661                                                         }
2662                                                         //search Content_Length result is OK
2663                                                         else {
2664                                                                 //http_header context is "\r\n\r\n" only
2665                                                                 if (http_header_all_len == 0) {
2666                                                                         //set current message rest size
2667                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + CR_LF_LEN;
2668                                                                 } else {
2669                                                                         //set current message rest size
2670                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + CR_LF_CR_LF_LEN;
2671                                                                 }
2672
2673                                                         }
2674                                                         
2675                                                         //increment http statistics
2676                                                         increment_stats(session_data_ptr->data_buffer + session_data_ptr->data_offset);
2677                                                         /*-------- DEBUG LOG --------*/
2678                                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2679                                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2680                                                                                         "handle_realserver_send() : call increment_stats : thread id : %d.");
2681                                                                 formatter % boost::this_thread::get_id();
2682                                                                 putLogDebug(600229, formatter.str(), __FILE__, __LINE__);
2683                                                         }
2684                                                         /*------DEBUG LOG END------*/
2685         
2686                                                         //set data state HTTP_HEADER
2687                                                         session_data_ptr->data_state = HTTP_HEADER;
2688                                                 }
2689
2690                                                 //set return status
2691                                                 status = REALSERVER_CONNECT;
2692                                         }
2693                                 }
2694                                 //data state is UNKNOWN
2695                                 else if (session_data_ptr->data_state == UNKNOWN) {
2696                                         //set return status
2697                                         status = REALSERVER_CONNECT;
2698                                 }
2699
2700                         }
2701                         //data size is 0
2702                         else {
2703                                 //data state is HTTP_BODY
2704                                 if (session_data_ptr->data_state == HTTP_BODY) {
2705                                         //set data state HTTP_START
2706                                         session_data_ptr->data_state = HTTP_START;
2707                                 }
2708
2709                                 //set data offset 0
2710                                 session_data_ptr->data_offset = 0;
2711
2712                                 //set return status
2713                                 status = CLIENT_RECV;
2714                         }
2715                 }
2716                 //set last status
2717                 session_data_ptr->last_status = status;
2718         } catch (int e) {
2719                 /*-------- DEBUG LOG --------*/
2720                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2721                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2722                                                 "handle_realserver_send() : catch exception e = %d. thread id : %d.");
2723                         formatter % e % boost::this_thread::get_id();
2724                         putLogDebug(600085, formatter.str(), __FILE__, __LINE__);
2725                 }
2726                 /*------DEBUG LOG END------*/
2727
2728                 //set return status
2729                 status = FINALIZE;
2730         } catch (const boost::bad_lexical_cast &) {
2731                 std::cerr << "protocol_module_ip::handle_realserver_send() : exception : " <<  "Content_Length field's value is invalid." << std::endl;
2732                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_send() : "
2733                                         "Content_Length field's value is invalid. thread id : %d.");
2734                 formatter % boost::this_thread::get_id();
2735                 putLogError(600052, formatter.str(), __FILE__, __LINE__);
2736
2737                 //set return status
2738                 status = FINALIZE;
2739         } catch (const std::exception &ex) {
2740                 std::cerr << "protocol_module_ip::handle_realserver_send() : exception : error = " << ex.what() << "." << std::endl;                //set data state HTTP_HEADER
2741                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2742                                         "handle_realserver_send() : exception : error = %s. thread id : %d.");
2743                 formatter % ex.what() % boost::this_thread::get_id();
2744                 putLogError(600053, formatter.str(), __FILE__, __LINE__);
2745
2746                 //set return status
2747                 status = FINALIZE;
2748         } catch (...) {
2749                 std::cerr << "protocol_module_ip::handle_realserver_send() : Unknown exception." << std::endl;
2750                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
2751                                         "protocol_module_ip::handle_realserver_send() : "
2752                                         "Unknown exception. thread id : %d.");
2753                 formatter % boost::this_thread::get_id();
2754                 putLogError(600054, formatter.str(), __FILE__, __LINE__);
2755
2756                 //set return status
2757                 status = FINALIZE;
2758         }
2759
2760         /*-------- DEBUG LOG --------*/
2761         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2762                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2763                                         "handle_realserver_send(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
2764                 formatter % status % boost::this_thread::get_id();
2765                 putLogDebug(600086, formatter.str(), __FILE__, __LINE__);
2766         }
2767         /*------DEBUG LOG END------*/
2768
2769         return status;
2770 }
2771
2772 //! called from after sorryserver select
2773 //! @param[in]    upstream thread id
2774 //! @param[in]    sorryserver endpoint reference
2775 //! @return        session use EVENT mode.
2776 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_select(
2777         const boost::thread::id thread_id, boost::asio::ip::tcp::endpoint &sorry_endpoint)
2778 {
2779         /*-------- DEBUG LOG --------*/
2780         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2781                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2782                                         "handle_sorryserver_select(const boost::thread::id thread_id, "
2783                                         "boost::asio::ip::tcp::endpoint& sorry_endpoint) : "
2784                                         "thread_id = %d, sorry_endpoint = [%s]:%d.");
2785                 formatter % thread_id % sorry_endpoint.address().to_string() % sorry_endpoint.port();
2786                 putLogDebug(600087, formatter.str(), __FILE__, __LINE__);
2787         }
2788         /*------DEBUG LOG END------*/
2789
2790         EVENT_TAG status = FINALIZE;
2791         boost::asio::ip::tcp::endpoint tmp_endpoint;
2792         thread_data_ptr session_data_ptr;
2793         session_thread_data_map_it session_thread_it;
2794         session_thread_data_map_it session_thread_it_end;
2795
2796         try {
2797                 {
2798                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
2799
2800                         session_thread_it = session_thread_data_map.find(thread_id);
2801                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
2802                                 boost::format formatter("Invalid thread id. thread id : %d.");
2803                                 formatter % boost::this_thread::get_id();
2804                                 putLogError(600055, formatter.str(), __FILE__, __LINE__);
2805                                 throw - 1;
2806                         }
2807
2808                         session_data_ptr = session_thread_it->second;
2809                 }
2810
2811                 //data state is HTTP_START
2812                 if (session_data_ptr->data_state == HTTP_START) {
2813                         //set return status
2814                         status = CLIENT_RECV;
2815                 }
2816                 //data state is not HTTP_START
2817                 else {
2818                         //set return status
2819                         status = SORRYSERVER_CONNECT;
2820                 }
2821
2822                 //set last status
2823                 session_data_ptr->last_status = status;
2824         } catch (int e) {
2825                 /*-------- DEBUG LOG --------*/
2826                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2827                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2828                                                 "handle_sorryserver_select() : catch exception e = %d. thread id : %d.");
2829                         formatter % e % boost::this_thread::get_id();
2830                         putLogDebug(600088, formatter.str(), __FILE__, __LINE__);
2831                 }
2832                 /*------DEBUG LOG END------*/
2833
2834                 //set return status
2835                 status = FINALIZE;
2836         } catch (const std::exception &ex) {
2837                 std::cerr << "protocol_module_ip::handle_sorryserver_select() : exception : error = " << ex.what() << "." << std::endl;
2838                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2839                                         "handle_sorryserver_select() : exception : error = %s. thread id : %d.");
2840                 formatter % ex.what() % boost::this_thread::get_id();
2841                 putLogError(600056, formatter.str(), __FILE__, __LINE__);
2842
2843                 //set return status
2844                 status = FINALIZE;
2845         } catch (...) {
2846                 std::cerr << "protocol_module_ip::handle_sorryserver_select() : Unknown exception." << std::endl;
2847                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
2848                                         "protocol_module_ip::handle_sorryserver_select() : "
2849                                         "Unknown exception. thread id : %d.");
2850                 formatter % boost::this_thread::get_id();
2851                 putLogError(600057, formatter.str(), __FILE__, __LINE__);
2852
2853                 //set return status
2854                 status = FINALIZE;
2855         }
2856
2857         /*-------- DEBUG LOG --------*/
2858         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2859                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2860                                         "handle_sorryserver_select(const boost::thread::id thread_id, "
2861                                         "boost::asio::ip::tcp::endpoint& sorry_endpoint)"
2862                                         " : return_value = %d. thread id : %d.");
2863                 formatter % status % boost::this_thread::get_id();
2864                 putLogDebug(600089, formatter.str(), __FILE__, __LINE__);
2865         }
2866         /*------DEBUG LOG END------*/
2867
2868         return status;
2869 }
2870
2871 //! called from after sorryserver connect
2872 //!    @param[in]    upstream thread id
2873 //! @param[out]    send buffer reference.
2874 //! @param[out]    send length
2875 //! @return        session use EVENT mode.
2876 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_connect(
2877         const boost::thread::id thread_id, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen)
2878 {
2879         /*-------- DEBUG LOG --------*/
2880         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2881                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2882                                         "handle_sorryserver_connect(const boost::thread::id thread_id, "
2883                                         "boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t& datalen) : "
2884                                         "thread_id = %d.");
2885                 formatter % thread_id;
2886                 putLogDebug(600090, formatter.str(), __FILE__, __LINE__);
2887         }
2888         /*------DEBUG LOG END------*/
2889
2890         EVENT_TAG status            = FINALIZE;
2891         size_t send_possible_size        = 0;
2892         size_t uri_offset            = 0;
2893         size_t uri_len                = 0;
2894         size_t x_forwarded_for_insert_pos   = 0;
2895         thread_data_ptr                session_data_ptr;
2896         session_thread_data_map_it        session_thread_it;
2897         std::pair<char *, size_t>        buffer_element;
2898         std::string                x_forwarded_for_context;
2899
2900         try {
2901                 {
2902                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
2903
2904                         //thread id check
2905                         session_thread_it = session_thread_data_map.find(thread_id);
2906                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
2907                                 boost::format formatter("Invalid thread id. thread id : %d.");
2908                                 formatter % boost::this_thread::get_id();
2909                                 putLogError(600058, formatter.str(), __FILE__, __LINE__);
2910                                 throw - 1;
2911                         }
2912
2913                         session_data_ptr = session_thread_it->second;
2914                 }
2915                 //set send possible data size
2916                 send_possible_size = std::min(session_data_ptr->current_message_rest_size,
2917                                               session_data_ptr->data_length
2918                                              );
2919
2920                 if (session_data_ptr->buffer_sequence.empty()) {
2921                         //data state is HTTP_HEADER
2922                         if (session_data_ptr->data_state == HTTP_HEADER) {
2923                                 //search uri
2924                                 http_utility::find_uri(session_data_ptr->data_buffer + session_data_ptr->data_offset,
2925                                                        session_data_ptr->data_length, uri_offset, uri_len);
2926
2927                                 //set buffer's position
2928                                 buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset;
2929                                 buffer_element.second = uri_offset;
2930
2931                                 //put buffer data to buffer_sequence
2932                                 session_data_ptr->buffer_sequence.push_back(buffer_element);
2933
2934                                 //set buffer's position
2935                                 buffer_element.first = sorry_uri.data();
2936                                 buffer_element.second = strlen(sorry_uri.data());
2937
2938                                 //put buffer data to buffer_sequence
2939                                 session_data_ptr->buffer_sequence.push_back(buffer_element);
2940
2941                                 //forwarded_for flag is on
2942                                 if (forwarded_for == FORWARDED_FOR_ON) {
2943                                         create_x_forwarded_for(session_data_ptr->client_endpoint.address().to_string(),
2944                                                                session_data_ptr->data_buffer + session_data_ptr->data_offset,
2945                                                                session_data_ptr->data_length,
2946                                                                x_forwarded_for_insert_pos,
2947                                                                x_forwarded_for_context);
2948
2949                                         //set buffer's position
2950                                         buffer_element.first = session_data_ptr->data_buffer
2951                                                                + session_data_ptr->data_offset
2952                                                                + uri_offset
2953                                                                + uri_len;
2954                                         buffer_element.second = x_forwarded_for_insert_pos - uri_offset - uri_len;
2955
2956                                         //put buffer data to buffer_sequence
2957                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2958
2959                                         session_data_ptr->forwarded_for_buffer.assign(0);
2960
2961                                         /*-------- DEBUG LOG --------*/
2962                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2963                                                 std::string datadump;
2964                                                 dump_memory(x_forwarded_for_context.c_str(),
2965                                                             x_forwarded_for_context.size(), datadump);
2966                                                 boost::format formatter(
2967                                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2968                                                         "handle_sorryserver_connect() : before memcpy (data dump) : "
2969                                                         "data begin = 0, data_size = %d, data = %s");
2970                                                 formatter %  x_forwarded_for_context.size() % datadump;
2971                                                 putLogDebug(600091, formatter.str(), __FILE__, __LINE__);
2972                                         }
2973                                         /*------DEBUG LOG END------*/
2974
2975                                         memcpy(session_data_ptr->forwarded_for_buffer.data(),
2976                                                x_forwarded_for_context.c_str(),
2977                                                x_forwarded_for_context.size());
2978
2979                                         /*-------- DEBUG LOG --------*/
2980                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2981                                                 std::string datadump;
2982                                                 dump_memory(x_forwarded_for_context.c_str(),
2983                                                             x_forwarded_for_context.size(), datadump);
2984                                                 boost::format formatter(
2985                                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2986                                                         "handle_sorryserver_connect() : after memcpy (data dump) : "
2987                                                         "data begin = 0, data_size = %d, data = %s");
2988                                                 formatter % x_forwarded_for_context.size() % datadump;
2989                                                 putLogDebug(600092, formatter.str(), __FILE__, __LINE__);
2990                                         }
2991                                         /*------DEBUG LOG END------*/
2992
2993                                         //set buffer's position
2994                                         buffer_element.first = session_data_ptr->forwarded_for_buffer.data();
2995                                         buffer_element.second = x_forwarded_for_context.size();
2996                                         //put buffer data to buffer_sequence
2997                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2998
2999                                         //set buffer's position
3000                                         buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset + x_forwarded_for_insert_pos;
3001                                         buffer_element.second = send_possible_size - x_forwarded_for_insert_pos;
3002                                         //put buffer data to buffer_sequence
3003                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
3004                                 }
3005                                 //forwarded_for flag is on
3006                                 else {
3007                                         //set buffer's position
3008                                         buffer_element.first = session_data_ptr->data_buffer
3009                                                                + session_data_ptr->data_offset
3010                                                                + uri_offset
3011                                                                + uri_len;
3012                                         buffer_element.second = send_possible_size - uri_offset - uri_len;
3013                                         //put buffer data to buffer_sequence
3014                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
3015                                 }
3016
3017                                 //set data state HTTP_BODY
3018                                 session_data_ptr->data_state = HTTP_BODY;
3019                         }
3020                         //data state is not HTTP_HEADER
3021                         else {
3022                                 //set buffer's position
3023                                 buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset;
3024                                 buffer_element.second = send_possible_size;
3025                                 //put buffer data to buffer_sequence
3026                                 session_data_ptr->buffer_sequence.push_back(buffer_element);
3027                         }
3028                 }
3029
3030                 //put buffer_sequence data into sendbuffer
3031                 put_data_into_sendbuffer(session_data_ptr, sendbuffer, datalen);
3032
3033                 //set return status
3034                 status = SORRYSERVER_SEND;
3035
3036                 //set last status
3037                 session_data_ptr->last_status = status;
3038
3039         } catch (int e) {
3040                 /*-------- DEBUG LOG --------*/
3041                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3042                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3043                                                 "handle_sorryserver_connect() : catch exception e = %d. thread id : %d.");
3044                         formatter % e % boost::this_thread::get_id();
3045                         putLogDebug(600093, formatter.str(), __FILE__, __LINE__);
3046                 }
3047                 /*------DEBUG LOG END------*/
3048
3049                 //set return status
3050                 status = FINALIZE;
3051         } catch (const std::exception &ex) {
3052                 std::cerr << "protocol_module_ip::handle_sorryserver_connect() : exception : error = " << ex.what() << "." << std::endl;
3053                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3054                                         "handle_sorryserver_connect() : exception : error = %s. thread id : %d.");
3055                 formatter % ex.what() % boost::this_thread::get_id();
3056                 putLogError(600059, formatter.str(), __FILE__, __LINE__);
3057
3058                 //set return status
3059                 status = FINALIZE;
3060         } catch (...) {
3061                 std::cerr << "protocol_module_ip::handle_sorryserver_connect() : Unknown exception." << std::endl;
3062                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3063                                         "handle_sorryserver_connect() : Unknown exception. thread id : %d.");
3064                 formatter % boost::this_thread::get_id();
3065                 putLogError(600060, formatter.str(), __FILE__, __LINE__);
3066
3067                 //set return status
3068                 status = FINALIZE;
3069         }
3070
3071         /*-------- DEBUG LOG --------*/
3072         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3073                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3074                                         "handle_sorryserver_connect(const boost::thread::id thread_id, "
3075                                         "boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
3076                                         "size_t& datalen) : return_value = %d. thread id : %d.");
3077                 formatter % status % boost::this_thread::get_id();
3078                 putLogDebug(600094, formatter.str(), __FILE__, __LINE__);
3079         }
3080         /*------DEBUG LOG END------*/
3081
3082         return status;
3083 }
3084 //! called from after sorryserver connection fail
3085 //! @param[in]    upstream thread id
3086 //! @param[in]    sorryserver endpoint reference.
3087 //! @return        session use EVENT mode.
3088 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_connection_fail(
3089         const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &sorry_endpoint)
3090 {
3091         /*-------- DEBUG LOG --------*/
3092         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3093                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3094                                         "handle_sorryserver_connection_fail(const boost::thread::id thread_id, "
3095                                         "const boost::asio::ip::tcp::endpoint& sorry_endpoint) : "
3096                                         "thread_id = %d, sorry_endpoint = [%s]:%d.");
3097                 formatter % thread_id % sorry_endpoint.address().to_string() % sorry_endpoint.port();
3098                 putLogDebug(600095, formatter.str(), __FILE__, __LINE__);
3099         }
3100         /*------DEBUG LOG END------*/
3101
3102         EVENT_TAG status = FINALIZE;
3103         thread_data_ptr session_data_ptr;
3104         session_thread_data_map_it session_thread_it;
3105
3106         try {
3107                 boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
3108
3109                 session_thread_it = session_thread_data_map.find(thread_id);
3110                 if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
3111                         boost::format formatter("Invalid thread id. thread id : %d.");
3112                         formatter % boost::this_thread::get_id();
3113                         putLogError(600061, formatter.str(), __FILE__, __LINE__);
3114                         throw - 1;
3115                 }
3116
3117                 session_data_ptr = session_thread_it->second;
3118
3119                 //set return status
3120                 status = CLIENT_DISCONNECT;
3121
3122                 //set last status
3123                 session_data_ptr->last_status = status;
3124         } catch (int e) {
3125                 /*-------- DEBUG LOG --------*/
3126                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3127                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3128                                                 "handle_sorryserver_connection_fail() : catch exception e = %d. thread id : %d.");
3129                         formatter % e % boost::this_thread::get_id();
3130                         putLogDebug(600096, formatter.str(), __FILE__, __LINE__);
3131                 }
3132                 /*------DEBUG LOG END------*/
3133
3134                 //set return status
3135                 status = FINALIZE;
3136         } catch (const std::exception &ex) {
3137                 std::cerr << "protocol_module_ip::handle_sorryserver_connection_fail() : exception : error = " << ex.what() << "." << std::endl;
3138                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3139                                         "handle_sorryserver_connection_fail() : exception : error = %s. thread id : %d.");
3140                 formatter % ex.what() % boost::this_thread::get_id();
3141                 putLogError(600062, formatter.str(), __FILE__, __LINE__);
3142
3143                 //set return status
3144                 status = FINALIZE;
3145         } catch (...) {
3146                 std::cerr << "protocol_module_ip::handle_sorryserver_connection_fail() : Unknown exception." << std::endl;
3147                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
3148                                         "protocol_module_ip::handle_sorryserver_connection_fail() : "
3149                                         "Unknown exception. thread id : %d.");
3150                 formatter % boost::this_thread::get_id();
3151                 putLogError(600063, formatter.str(), __FILE__, __LINE__);
3152
3153                 //set return status
3154                 status = FINALIZE;
3155         }
3156
3157         /*-------- DEBUG LOG --------*/
3158         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3159                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3160                                         "handle_sorryserver_connection_fail(const boost::thread::id thread_id, "
3161                                         "const boost::asio::ip::tcp::endpoint& sorry_endpoint) : return_value = %d. thread id : %d.");
3162                 formatter % status % boost::this_thread::get_id();
3163                 putLogDebug(600097, formatter.str(), __FILE__, __LINE__);
3164         }
3165         /*------DEBUG LOG END------*/
3166
3167         return status;
3168 }
3169
3170 //! called from after sorryserver send
3171 //! @param[in]    upstream thread id
3172 //! @return        session use EVENT mode.
3173 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_send(
3174         const boost::thread::id thread_id)
3175 {
3176         /*-------- DEBUG LOG --------*/
3177         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3178                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3179                                         "handle_sorryserver_send(const boost::thread::id thread_id) : thread_id = %d.");
3180                 formatter % thread_id;
3181                 putLogDebug(600098, formatter.str(), __FILE__, __LINE__);
3182         }
3183         /*------DEBUG LOG END------*/
3184
3185         EVENT_TAG status                = FINALIZE;
3186         size_t http_header_all_offset            = 0;
3187         size_t http_header_all_len            = 0;
3188         size_t http_header_content_length_offset    = 0;
3189         size_t http_header_content_length_len        = 0;
3190         const size_t CR_LF_LEN                = 2;
3191         const size_t CR_LF_CR_LF_LEN            = 4;
3192         int content_length_value            = 0;
3193
3194         std::string content_length;
3195         cmatch regex_ret;
3196         cregex content_length_regex = icase("Content-Length") >> ":" >> *~_d >> (s1 = +_d) >> *~_d;
3197
3198
3199         bool find_ret = false;
3200         http_utility::CHECK_RESULT_TAG check_ret;
3201
3202         thread_data_ptr session_data_ptr;
3203         session_thread_data_map_it session_thread_it;
3204
3205         try {
3206                 {
3207                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
3208
3209                         //thread id check
3210                         session_thread_it = session_thread_data_map.find(thread_id);
3211                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
3212                                 boost::format formatter("Invalid thread id. thread id : %d.");
3213                                 formatter % boost::this_thread::get_id();
3214                                 putLogError(600064, formatter.str(), __FILE__, __LINE__);
3215                                 throw - 1;
3216                         }
3217
3218                         session_data_ptr = session_thread_it->second;
3219                 }
3220
3221                 //current_message_rest_size > 0
3222                 if (session_data_ptr->current_message_rest_size > 0) {
3223                         //data size > 0
3224                         if (session_data_ptr->data_length > 0) {
3225                                 //set return status
3226                                 status = SORRYSERVER_CONNECT;
3227                         }
3228                         //data size is 0
3229                         else {
3230                                 //data offset is 0
3231                                 session_data_ptr->data_offset = 0;
3232
3233                                 //set return status
3234                                 status =  CLIENT_RECV;
3235                         }
3236                 }
3237                 //current_message_rest_size is 0
3238                 else {
3239                         //data size > 0
3240                         if (session_data_ptr->data_length > 0) {
3241                                 //data state is HTTP_BODY
3242                                 if (session_data_ptr->data_state == HTTP_BODY) {
3243                                         //search whole http header, get whole http header's offset and length
3244                                         find_ret = http_utility::find_http_header_all(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3245                                                         session_data_ptr->data_length,
3246                                                         http_header_all_offset,
3247                                                         http_header_all_len
3248                                                                                      );
3249
3250                                         /*-------- DEBUG LOG --------*/
3251                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3252                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3253                                                                         "handle_sorryserver_send() : call find_http_header_all : "
3254                                                                         "return_value = %d. thread id : %d.");
3255                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
3256                                                 putLogDebug(600099, formatter.str(), __FILE__, __LINE__);
3257                                         }
3258                                         /*------DEBUG LOG END------*/
3259
3260                                         //search http header result is NG
3261                                         if (!find_ret) {
3262                                                 //set data state HTTP_START
3263                                                 session_data_ptr->data_state = HTTP_START;
3264
3265                                                 //set return status
3266                                                 status = CLIENT_RECV;
3267                                         }
3268                                         //check method and version result is OK
3269                                         else {
3270                                                 //search Content_Length header
3271                                                 check_ret = http_utility::check_http_method_and_version(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3272                                                                 session_data_ptr->data_length);
3273
3274                                                 /*-------- DEBUG LOG --------*/
3275                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3276                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3277                                                                                 "handle_sorryserver_send() : call check_http_method_and_version : "
3278                                                                                 "return_value = %d. thread id : %d.");
3279                                                         formatter % check_ret % boost::this_thread::get_id();
3280                                                         putLogDebug(600100, formatter.str(), __FILE__, __LINE__);
3281                                                 }
3282                                                 /*------DEBUG LOG END------*/
3283
3284                                                 //check method and version result is NG
3285                                                 if (check_ret == http_utility::CHECK_NG) {
3286                                                         //set current message rest size
3287                                                         session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3288
3289                                                         //set data state UNKNOWN
3290                                                         session_data_ptr->data_state = UNKNOWN;
3291                                                 }
3292                                                 //check method and version result is OK
3293                                                 else {
3294                                                         //search Content_Length header
3295                                                         find_ret = http_utility::find_http_header_content_length(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3296                                                                         session_data_ptr->data_length,
3297                                                                         http_header_content_length_offset,
3298                                                                         http_header_content_length_len);
3299
3300                                                         /*-------- DEBUG LOG --------*/
3301                                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3302                                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3303                                                                                         "handle_sorryserver_send() : call find_http_header_content_length : "
3304                                                                                         "return_value = %d. thread id : %d.");
3305                                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
3306                                                                 putLogDebug(600101, formatter.str(), __FILE__, __LINE__);
3307                                                         }
3308                                                         /*------DEBUG LOG END------*/
3309
3310                                                         //search Content_Length result is OK
3311                                                         if (find_ret) {
3312                                                                 content_length.assign(session_data_ptr->data_buffer + session_data_ptr->data_offset + http_header_content_length_offset,
3313                                                                                       http_header_content_length_len);
3314                                                                 find_ret = regex_search(content_length.c_str(), regex_ret, content_length_regex);
3315
3316                                                                 //"content-length: ddd\r\n"
3317                                                                 if (find_ret) {
3318                                                                         content_length = content_length.substr(
3319                                                                                                  regex_ret.position(1),
3320                                                                                                  regex_ret.length(1));
3321
3322                                                                         //set content length value
3323                                                                         content_length_value = boost::lexical_cast<int>(content_length);
3324                                                                 }
3325
3326                                                                 //http_header context is "\r\n\r\n" only
3327                                                                 if (http_header_all_len == 0) {
3328                                                                         //set current message rest size
3329                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + content_length_value + CR_LF_LEN;
3330                                                                 } else {
3331                                                                         //set current message rest size
3332                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + content_length_value + CR_LF_CR_LF_LEN;
3333                                                                 }
3334                                                         }
3335                                                         //search Content_Length result is OK
3336                                                         else {
3337                                                                 //http_header context is "\r\n\r\n" only
3338                                                                 if (http_header_all_len == 0) {
3339                                                                         //set current message rest size
3340                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + CR_LF_LEN;
3341                                                                 } else {
3342                                                                         //set current message rest size
3343                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + CR_LF_CR_LF_LEN;
3344                                                                 }
3345
3346                                                         }
3347
3348                                                         //set data state HTTP_HEADER
3349                                                         session_data_ptr->data_state = HTTP_HEADER;
3350
3351                                                 }
3352                                                 //set return status
3353                                                 status = SORRYSERVER_CONNECT;
3354                                         }
3355                                 }
3356                                 //data state is UNKNOWN
3357                                 else if (session_data_ptr->data_state == UNKNOWN) {
3358                                         //set return status
3359                                         status = SORRYSERVER_CONNECT;
3360                                 }
3361
3362                         }
3363                         //data size is 0
3364                         else {
3365                                 //data state is HTTP_BODY
3366                                 if (session_data_ptr->data_state == HTTP_BODY) {
3367                                         //set data state HTTP_START
3368                                         session_data_ptr->data_state = HTTP_START;
3369                                 }
3370
3371                                 //set data offset 0
3372                                 session_data_ptr->data_offset = 0;
3373
3374                                 //set return status
3375                                 status = CLIENT_RECV;
3376                         }
3377                 }
3378
3379                 //set last status
3380                 session_data_ptr->last_status = status;
3381         } catch (int e) {
3382                 /*-------- DEBUG LOG --------*/
3383                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3384                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3385                                                 "handle_sorryserver_send() : catch exception e = %d. thread id : %d.");
3386                         formatter % e % boost::this_thread::get_id();
3387                         putLogDebug(600102, formatter.str(), __FILE__, __LINE__);
3388                 }
3389                 /*------DEBUG LOG END------*/
3390
3391                 //set return status
3392                 status = FINALIZE;
3393         } catch (const boost::bad_lexical_cast &) {
3394                 std::cerr << "protocol_module_ip::handle_sorryserver_send() : exception : " <<  "Content_Length field's value is invalid." << std::endl;
3395                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_send() : "
3396                                         "Content_Length field's value is invalid. thread id : %d.");
3397                 formatter % boost::this_thread::get_id();
3398                 putLogError(600065, formatter.str(), __FILE__, __LINE__);
3399
3400                 //set return status
3401                 status = FINALIZE;
3402         } catch (const std::exception &ex) {
3403                 std::cerr << "protocol_module_ip::handle_sorryserver_send() : exception : error = " << ex.what() << "." << std::endl;
3404                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3405                                         "handle_sorryserver_send() : exception : error = %s. thread id : %d.");
3406                 formatter % ex.what() % boost::this_thread::get_id();
3407                 putLogError(600066, formatter.str(), __FILE__, __LINE__);
3408
3409                 //set return status
3410                 status = FINALIZE;
3411         } catch (...) {
3412                 std::cerr << "protocol_module_ip::handle_sorryserver_send() : Unknown exception." << std::endl;
3413                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
3414                                         "protocol_module_ip::handle_sorryserver_send() : "
3415                                         "Unknown exception. thread id : %d.");
3416                 formatter % boost::this_thread::get_id();
3417                 putLogError(600067, formatter.str(), __FILE__, __LINE__);
3418
3419                 //set return status
3420                 status = FINALIZE;
3421         }
3422
3423         /*-------- DEBUG LOG --------*/
3424         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3425                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3426                                         "handle_sorryserver_send(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
3427                 formatter % status % boost::this_thread::get_id();
3428                 putLogDebug(600103, formatter.str(), __FILE__, __LINE__);
3429         }
3430         /*------DEBUG LOG END------*/
3431
3432         return status;
3433 }
3434
3435 //! called from after realserver receive.for UDP
3436 //! @param[in]    downstream thread id
3437 //! @param[in]    realserver UDP endpoint reference
3438 //! @param[in]    receive from realserver buffer reference
3439 //! @param[in]    recv data length
3440 //! @return        session use EVENT mode.
3441 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_recv(
3442         const boost::thread::id thread_id, const boost::asio::ip::udp::endpoint &rs_endpoint, const boost::array < char,
3443         MAX_BUFFER_SIZE > & recvbuffer, const size_t recvlen)
3444 {
3445         /*-------- DEBUG LOG --------*/
3446         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3447                 boost::format formatter("in/out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3448                                         "handle_realserver_recv(const boost::thread::id thread_id, "
3449                                         "const boost::asio::ip::udp::endpoint& rs_endpoint, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3450                                         "const size_t& recvlen) : "
3451                                         "return_value = %d. thread id : %d.");
3452                 formatter % STOP % boost::this_thread::get_id();
3453                 putLogDebug(600104, formatter.str(), __FILE__, __LINE__);
3454         }
3455         /*------DEBUG LOG END------*/
3456         return STOP;
3457 }
3458
3459 //! called from after realserver receive for TCP/IP
3460 //! @param[in]    downstream thread id
3461 //! @param[in]    realserver TCP/IP endpoint reference
3462 //! @param[in]    realserver receive buffer reference.
3463 //! @param[in]    recv data length
3464 //! @return        session use EVENT mode.
3465 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_recv(
3466         const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &rs_endpoint, const boost::array < char,
3467         MAX_BUFFER_SIZE > & recvbuffer, const size_t recvlen)
3468 {
3469         /*-------- DEBUG LOG --------*/
3470         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3471                 size_t buffer_size = recvbuffer.size() < recvlen ? recvbuffer.size() : recvlen;
3472                 std::string buffer;
3473                 dump_memory(recvbuffer.data(), buffer_size, buffer);
3474                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3475                                         "handle_realserver_recv(const boost::thread::id thread_id, "
3476                                         "const boost::asio::ip::tcp::endpoint& rs_endpoint, "
3477                                         "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3478                                         "const size_t recvlen) : thread_id = %d, rs_endpoint = [%s]:%d, recvbuffer = %s, recvlen = %d.");
3479                 formatter % thread_id % rs_endpoint.address().to_string() % rs_endpoint.port()
3480                 % buffer % recvlen;
3481                 putLogDebug(600105, formatter.str(), __FILE__, __LINE__);
3482         }
3483         /*------DEBUG LOG END------*/
3484
3485         EVENT_TAG status                = FINALIZE;
3486
3487         bool find_ret                    = false;
3488         size_t http_header_offset            = 0;
3489         size_t http_header_len                = 0;
3490         size_t http_header_content_length_offset    = 0;
3491         size_t http_header_content_length_len        = 0;
3492         int content_length_value            = 0;
3493         const size_t CR_LF_LEN                = 2; //length of "\r\n"
3494         const size_t CR_LF_CR_LF_LEN            = 4; //length of "\r\n\r\n"
3495
3496         session_thread_data_map_it            session_thread_it;
3497         thread_data_ptr                    session_data_ptr;
3498         http_utility::CHECK_RESULT_TAG            check_ret;
3499
3500         std::string                    content_length;
3501         cmatch                        regex_ret;
3502         cregex content_length_regex = icase("Content-Length") >> ":" >> *~_d >> (s1 = +_d) >> *~_d;
3503
3504         if (unlikely(recvlen > recvbuffer.size())) {
3505                 std::cerr << "protocol_module_ip::handle_realserver_recv() : Data size bigger than buffer size." << std::endl;
3506                 boost::format formatter("Data size bigger than buffer size. thread id : %d.");
3507                 formatter % boost::this_thread::get_id();
3508                 putLogError(600068, formatter.str(), __FILE__, __LINE__);
3509
3510                 /*-------- DEBUG LOG --------*/
3511                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3512                         boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3513                                                 "handle_realserver_recv(const boost::thread::id thread_id, "
3514                                                 "const boost::asio::ip::tcp::endpoint& rs_endpoint, "
3515                                                 "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3516                                                 "const size_t recvlen) : return_value = %d. thread id : %d.");
3517                         formatter % FINALIZE % boost::this_thread::get_id();
3518                         putLogDebug(600106, formatter.str(), __FILE__, __LINE__);
3519                 }
3520                 /*------DEBUG LOG END------*/
3521
3522                 return status;
3523         }
3524
3525         try {
3526                 {
3527                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
3528
3529                         session_thread_it = session_thread_data_map.find(thread_id);
3530                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
3531                                 boost::format formatter("Invalid thread id. thread id : %d.");
3532                                 formatter % boost::this_thread::get_id();
3533                                 putLogError(600069, formatter.str(), __FILE__, __LINE__);
3534                                 throw - 1;
3535                         }
3536
3537                         session_data_ptr = session_thread_it->second;
3538                 }
3539
3540                 //set switch flag off
3541                 session_data_ptr->switch_flag = SWITCH_FLAG_OFF;
3542
3543                 /*-------- DEBUG LOG --------*/
3544                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3545                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3546                                                 "handle_realserver_recv(const boost::thread::id thread_id, "
3547                                                 "const boost::asio::ip::tcp::endpoint& rs_endpoint, "
3548                                                 "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3549                                                 "const size_t recvlen) : SWITCH_FLAG_OFF. "
3550                                                 "thread_id = %d, rs_endpoint = [%s]:%d.");
3551                         formatter % thread_id % rs_endpoint.address().to_string() % rs_endpoint.port();
3552                         putLogDebug(600107, formatter.str(), __FILE__, __LINE__);
3553                 }
3554                 /*------DEBUG LOG END------*/
3555
3556                 //copy data from recvbuffer
3557                 if (!get_data_from_recvbuffer(session_data_ptr, recvbuffer, recvlen)) {
3558                         //copy failed
3559                         std::cerr << "protocol_module_ip::handle_realserver_recv() : Data size bigger than buffer size." << std::endl;
3560                         boost::format formatter("Data size bigger than buffer size. thread id : % id.");
3561                         formatter % boost::this_thread::get_id();
3562                         putLogError(600070, formatter.str(), __FILE__, __LINE__);
3563                         status = FINALIZE;
3564                 } else {
3565                         if (forwarded_for == FORWARDED_FOR_OFF && session_data_ptr->sorry_flag == SORRY_FLAG_OFF) {
3566                                 session_data_ptr->data_state = UNKNOWN;
3567                         }
3568                         //data state is HTTP_START
3569                         if (session_data_ptr->data_state == HTTP_START) {
3570                                 //search http header
3571                                 find_ret = http_utility::find_http_header_all(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3572                                                 session_data_ptr->data_length,
3573                                                 http_header_offset,
3574                                                 http_header_len
3575                                                                              );
3576
3577                                 /*-------- DEBUG LOG --------*/
3578                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3579                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3580                                                                 "handle_realserver_recv() : call find_http_header_all : "
3581                                                                 "return_value = %d. thread id : %d.");
3582                                         formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
3583                                         putLogDebug(600108, formatter.str(), __FILE__, __LINE__);
3584                                 }
3585                                 /*------DEBUG LOG END------*/
3586
3587                                 //search http header result is NG
3588                                 if (!find_ret) {
3589                                         //data size bigger than max buffer size
3590                                         if (session_data_ptr->data_length >= MAX_IP_MODULE_BUFFER_SIZE - recvbuffer.size()) {
3591                                                 //set data state UNKNOWN
3592                                                 session_data_ptr->data_state = UNKNOWN;
3593                                                 //set current message rest size
3594                                                 session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3595                                         }
3596                                 }
3597                                 //search http header result is OK
3598                                 else {
3599                                         //check http version and status code
3600                                         check_ret = http_utility::check_http_version_and_status_code(session_data_ptr->data_buffer,
3601                                                         session_data_ptr->data_length);
3602
3603                                         /*-------- DEBUG LOG --------*/
3604                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3605                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3606                                                                         "handle_realserver_recv() : call check_http_version_and_status_code : "
3607                                                                         "return_value = %d. thread id : %d.");
3608                                                 formatter % check_ret % boost::this_thread::get_id();
3609                                                 putLogDebug(600109, formatter.str(), __FILE__, __LINE__);
3610                                         }
3611                                         /*------DEBUG LOG END------*/
3612
3613                                         //check http version and status code result is NG
3614                                         if (check_ret == http_utility::CHECK_NG) {
3615                                                 //set data state UNKNOWN
3616                                                 session_data_ptr->data_state = UNKNOWN;
3617                                                 //set current message rest size
3618                                                 session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3619                                         }
3620                                         //check http version and status code result is OK
3621                                         else {
3622                                                 //search Content_Length header
3623                                                 find_ret = http_utility::find_http_header_content_length(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3624                                                                 session_data_ptr->data_length,
3625                                                                 http_header_content_length_offset,
3626                                                                 http_header_content_length_len);
3627
3628                                                 /*-------- DEBUG LOG --------*/
3629                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3630                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3631                                                                                 "handle_realserver_recv() : call find_http_header_content_length : "
3632                                                                                 "return_value = %d. thread id : %d.");
3633                                                         formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
3634                                                         putLogDebug(600110, formatter.str(), __FILE__, __LINE__);
3635                                                 }
3636                                                 /*------DEBUG LOG END------*/
3637
3638                                                 //search Content_Length result is OK
3639                                                 if (find_ret) {
3640                                                         //set content length string
3641                                                         content_length.assign(session_data_ptr->data_buffer + session_data_ptr->data_offset + http_header_content_length_offset,
3642                                                                               http_header_content_length_len);
3643                                                         find_ret = regex_search(content_length.c_str(), regex_ret, content_length_regex);
3644
3645                                                         //"content-length: ddd\r\n"
3646                                                         if (find_ret) {
3647                                                                 content_length = content_length.substr(
3648                                                                                          regex_ret.position(1),
3649                                                                                          regex_ret.length(1));
3650
3651                                                                 //set content length value
3652                                                                 content_length_value = boost::lexical_cast<int>(content_length);
3653                                                         }
3654
3655                                                         //http_header context is "\r\n\r\n" only
3656                                                         if (http_header_len == 0) {
3657                                                                 //set current message rest size
3658                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + content_length_value + CR_LF_LEN;
3659                                                         } else {
3660                                                                 //set current message rest size
3661                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + content_length_value + CR_LF_CR_LF_LEN;
3662                                                         }
3663                                                 }
3664                                                 //search Content_Length result is NG
3665                                                 else {
3666                                                         //http_header context is "\r\n\r\n" only
3667                                                         if (http_header_len == 0) {
3668                                                                 //set current message rest size
3669                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + CR_LF_LEN;
3670                                                         } else {
3671                                                                 //set current message rest size
3672                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + CR_LF_CR_LF_LEN;
3673                                                         }
3674                                                 }
3675
3676                                                 //set data state HTTP_HEADER
3677                                                 session_data_ptr->data_state = HTTP_HEADER;
3678                                         }
3679                                 }
3680                         }
3681                         //data state is UNKNOWN
3682                         else if (session_data_ptr->data_state == UNKNOWN) {
3683                                 //set current message rest size
3684                                 session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3685                         } else {
3686                                 //none
3687                         }
3688
3689                         //data state is HTTP_START
3690                         if (session_data_ptr->data_state == HTTP_START) {
3691                                 //set return status
3692                                 status = REALSERVER_RECV;
3693                         }
3694                         //data state is not HTTP_START
3695                         else {
3696                                 //set return status
3697                                 status = CLIENT_CONNECTION_CHECK;
3698                         }
3699                 }
3700
3701                 //set last status
3702                 session_data_ptr->last_status = status;
3703         } catch (int e) {
3704                 /*-------- DEBUG LOG --------*/
3705                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3706                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3707                                                 "handle_realserver_recv() : catch exception e = %d. thread id : %d.");
3708                         formatter % e % boost::this_thread::get_id();
3709                         putLogDebug(600111, formatter.str(), __FILE__, __LINE__);
3710                 }
3711                 /*------DEBUG LOG END------*/
3712
3713                 //set return status
3714                 status = FINALIZE;
3715         } catch (const boost::bad_lexical_cast &) {
3716                 std::cerr << "protocol_module_ip::handle_realserver_recv() : exception : " <<  "Content_Length field's value is invalid." << std::endl;
3717                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_recv() : "
3718                                         "Content_Length field's value is invalid. thread id : %d.");
3719                 formatter % boost::this_thread::get_id();
3720                 putLogError(600071, formatter.str(), __FILE__, __LINE__);
3721
3722                 //set return status
3723                 status = FINALIZE;
3724         } catch (const std::exception &ex) {
3725                 std::cerr << "protocol_module_ip::handle_realserver_recv() : exception : error = " << ex.what() << "." << std::endl;
3726                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3727                                         "handle_realserver_recv() : exception : error = %s. thread id : %d.");
3728                 formatter % ex.what() % boost::this_thread::get_id();
3729                 putLogError(600072, formatter.str(), __FILE__, __LINE__);
3730
3731                 //set return status
3732                 status = FINALIZE;
3733         } catch (...) {
3734                 std::cerr << "protocol_module_ip::handle_realserver_recv() : Unknown exception." << std::endl;
3735                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
3736                                         "protocol_module_ip::handle_realserver_recv() : "
3737                                         "Unknown exception. thread id : %d.");
3738                 formatter % boost::this_thread::get_id();
3739                 putLogError(600073, formatter.str(), __FILE__, __LINE__);
3740
3741                 //set return status
3742                 status = FINALIZE;
3743         }
3744
3745         /*-------- DEBUG LOG --------*/
3746         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3747                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3748                                         "handle_realserver_recv(const boost::thread::id thread_id, "
3749                                         "const boost::asio::ip::tcp::endpoint& rs_endpoint, "
3750                                         "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3751                                         "const size_t recvlen) : return_value = %d. thread id : %d.");
3752                 formatter % FINALIZE % boost::this_thread::get_id();
3753                 putLogDebug(600112, formatter.str(), __FILE__, __LINE__);
3754         }
3755         /*------DEBUG LOG END------*/
3756
3757         return status;
3758 }
3759
3760
3761
3762 //! called from after sorryserver receive
3763 //! @param[in]    downstream thread id
3764 //! @param[in]    sorryserver endpoint reference
3765 //! @param[in]    receive from realserver buffer reference.
3766 //! @param[in]    recv data length
3767 //! @return     session use EVENT mode
3768 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_recv(
3769         const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &sorry_endpoint, const boost::array <
3770         char, MAX_BUFFER_SIZE > & recvbuffer, const size_t recvlen)
3771 {
3772         /*-------- DEBUG LOG --------*/
3773         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3774                 size_t buffer_size = recvbuffer.size() < recvlen ? recvbuffer.size() : recvlen;
3775                 std::string buffer;
3776                 dump_memory(recvbuffer.data(), buffer_size, buffer);
3777                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3778                                         "handle_sorryserver_recv(const boost::thread::id thread_id, "
3779                                         "const boost::asio::ip::tcp::endpoint& sorry_endpoint, "
3780                                         "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3781                                         "const size_t recvlen) : thread_id = %d, sorry_endpoint = [%s]:%d, recvbuffer = %s, recvlen = %d.");
3782                 formatter % thread_id % sorry_endpoint.address().to_string() % sorry_endpoint.port()
3783                 % buffer % recvlen;
3784                 putLogDebug(600113, formatter.str(), __FILE__, __LINE__);
3785         }
3786         /*------DEBUG LOG END------*/
3787
3788         EVENT_TAG status                = FINALIZE;
3789         bool find_ret                    = false;
3790         size_t http_header_offset            = 0;
3791         size_t http_header_len                = 0;
3792         size_t http_header_content_length_offset    = 0;
3793         size_t http_header_content_length_len        = 0;
3794         int content_length_value            = 0;
3795         const size_t CR_LF_LEN                = 2; //length of "\r\n"
3796         const size_t CR_LF_CR_LF_LEN            = 4; //length of "\r\n\r\n"
3797
3798         session_thread_data_map_it            session_thread_it;
3799         thread_data_ptr                    session_data_ptr;
3800         http_utility::CHECK_RESULT_TAG            check_ret;
3801         std::string                    content_length;
3802         cmatch                        regex_ret;
3803         cregex content_length_regex = icase("Content-Length") >> ":" >> *~_d >> (s1 = +_d) >> *~_d;
3804
3805         if (unlikely(recvlen > recvbuffer.size())) {
3806                 std::cerr << "protocol_module_ip::handle_sorryserver_recv() : Data size bigger than buffer size." << std::endl;
3807                 boost::format formatter("Data size bigger than buffer size. thread id : %d.");
3808                 formatter % boost::this_thread::get_id();
3809                 putLogError(600074, formatter.str(), __FILE__, __LINE__);
3810
3811                 /*-------- DEBUG LOG --------*/
3812                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3813                         boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3814                                                 "handle_sorryserver_recv(const boost::thread::id thread_id, "
3815                                                 "const boost::asio::ip::tcp::endpoint& sorry_endpoint, "
3816                                                 "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3817                                                 "const size_t recvlen) : return_value = %d. thread id : %d.");
3818                         formatter % FINALIZE % boost::this_thread::get_id();
3819                         putLogDebug(600114, formatter.str(), __FILE__, __LINE__);
3820                 }
3821                 /*------DEBUG LOG END------*/
3822
3823                 return status;
3824         }
3825
3826         try {
3827                 {
3828                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
3829
3830                         session_thread_it = session_thread_data_map.find(thread_id);
3831                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
3832                                 boost::format formatter("Invalid thread id. thread id : %d.");
3833                                 formatter % boost::this_thread::get_id();
3834                                 putLogError(600075, formatter.str(), __FILE__, __LINE__);
3835                                 throw - 1;
3836                         }
3837
3838                         session_data_ptr = session_thread_it->second;
3839                 }
3840
3841                 //set switch flag off
3842                 session_data_ptr->switch_flag = SWITCH_FLAG_OFF;
3843
3844                 /*-------- DEBUG LOG --------*/
3845                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3846                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3847                                                 "handle_sorryserver_recv(const boost::thread::id thread_id, "
3848                                                 "const boost::asio::ip::tcp::endpoint& sorry_endpoint, "
3849                                                 "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3850                                                 "const size_t recvlen) : SWITCH_FLAG_OFF. "
3851                                                 "thread_id = %d, rs_endpoint = [%s]:%d.");
3852                         formatter % thread_id % sorry_endpoint.address().to_string() % sorry_endpoint.port();
3853                         putLogDebug(600115, formatter.str(), __FILE__, __LINE__);
3854                 }
3855                 /*------DEBUG LOG END------*/
3856
3857                 //copy data from recvbuffer
3858                 if (!get_data_from_recvbuffer(session_data_ptr, recvbuffer, recvlen)) {
3859                         //copy failed
3860                         std::cerr << "protocol_module_ip::handle_sorryserver_recv() : Data size bigger than buffer size." << std::endl;
3861                         boost::format formatter("Data size bigger than buffer size. thread id : % id.");
3862                         formatter % boost::this_thread::get_id();
3863                         putLogError(600076, formatter.str(), __FILE__, __LINE__);
3864
3865                         status = FINALIZE;
3866                 } else {
3867                         if (forwarded_for == FORWARDED_FOR_OFF && session_data_ptr->sorry_flag == SORRY_FLAG_OFF) {
3868                                 session_data_ptr->data_state = UNKNOWN;
3869                         }
3870                         //data state is HTTP_START
3871                         if (session_data_ptr->data_state == HTTP_START) {
3872                                 //search http header
3873                                 find_ret = http_utility::find_http_header_all(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3874                                                 session_data_ptr->data_length,
3875                                                 http_header_offset,
3876                                                 http_header_len
3877                                                                              );
3878
3879                                 /*-------- DEBUG LOG --------*/
3880                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3881                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3882                                                                 "handle_sorryserver_recv() : call find_http_header_all : "
3883                                                                 "return_value = %d. thread id : %d.");
3884                                         formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
3885                                         putLogDebug(600116, formatter.str(), __FILE__, __LINE__);
3886                                 }
3887                                 /*------DEBUG LOG END------*/
3888
3889                                 //search http header result is NG
3890                                 if (!find_ret) {
3891                                         //data size bigger than max buffer size
3892                                         if (session_data_ptr->data_length >= MAX_IP_MODULE_BUFFER_SIZE - recvbuffer.size()) {
3893                                                 //set data state UNKNOWN
3894                                                 session_data_ptr->data_state = UNKNOWN;
3895                                                 //set current message rest size
3896                                                 session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3897                                         }
3898                                 }
3899                                 //search http header result is OK
3900                                 else {
3901                                         //check http version and status code
3902                                         check_ret = http_utility::check_http_version_and_status_code(session_data_ptr->data_buffer,
3903                                                         session_data_ptr->data_length);
3904
3905                                         /*-------- DEBUG LOG --------*/
3906                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3907                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3908                                                                         "handle_sorryserver_recv() : call check_http_version_and_status_code : "
3909                                                                         "return_value = %d. thread id : %d.");
3910                                                 formatter % check_ret % boost::this_thread::get_id();
3911                                                 putLogDebug(600117, formatter.str(), __FILE__, __LINE__);
3912                                         }
3913                                         /*------DEBUG LOG END------*/
3914
3915                                         //check http version and status code result is NG
3916                                         if (check_ret == http_utility::CHECK_NG) {
3917                                                 //set data state UNKNOWN
3918                                                 session_data_ptr->data_state = UNKNOWN;
3919                                                 //set current message rest size
3920                                                 session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3921                                         }
3922                                         //check http version and status code result is OK
3923                                         else {
3924                                                 //search Content_Length header
3925                                                 find_ret = http_utility::find_http_header_content_length(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3926                                                                 session_data_ptr->data_length,
3927                                                                 http_header_content_length_offset,
3928                                                                 http_header_content_length_len);
3929
3930                                                 /*-------- DEBUG LOG --------*/
3931                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3932                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3933                                                                                 "handle_sorryserver_recv() : call find_http_header_content_length : "
3934                                                                                 "return_value = %d. thread id : %d.");
3935                                                         formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
3936                                                         putLogDebug(600118, formatter.str(), __FILE__, __LINE__);
3937                                                 }
3938                                                 /*------DEBUG LOG END------*/
3939
3940                                                 //search Content_Length result is OK
3941                                                 if (find_ret) {
3942                                                         ////set content length string
3943                                                         content_length.assign(session_data_ptr->data_buffer + session_data_ptr->data_offset + http_header_content_length_offset,
3944                                                                               http_header_content_length_len);
3945                                                         find_ret = regex_search(content_length.c_str(), regex_ret, content_length_regex);
3946
3947                                                         //"content-length: ddd\r\n"
3948                                                         if (find_ret) {
3949                                                                 content_length = content_length.substr(
3950                                                                                          regex_ret.position(1),
3951                                                                                          regex_ret.length(1));
3952
3953                                                                 //set content length value
3954                                                                 content_length_value = boost::lexical_cast<int>(content_length);
3955                                                         }
3956
3957                                                         //http_header context is "\r\n\r\n" only
3958                                                         if (http_header_len == 0) {
3959                                                                 //set current message rest size
3960                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + content_length_value + CR_LF_LEN;
3961                                                         } else {
3962                                                                 //set current message rest size
3963                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + content_length_value + CR_LF_CR_LF_LEN;
3964                                                         }
3965                                                 }
3966                                                 //search Content_Length result is NG
3967                                                 else {
3968                                                         //http_header context is "\r\n\r\n" only
3969                                                         if (http_header_len == 0) {
3970                                                                 //set current message rest size
3971                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + CR_LF_LEN;
3972                                                         } else {
3973                                                                 //set current message rest size
3974                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + CR_LF_CR_LF_LEN;
3975                                                         }
3976
3977                                                 }
3978
3979                                                 //set data state HTTP_HEADER
3980                                                 session_data_ptr->data_state = HTTP_HEADER;
3981
3982                                         }
3983                                 }
3984                         }
3985                         //data state is UNKNOWN
3986                         else if (session_data_ptr->data_state == UNKNOWN) {
3987                                 //set current message rest size
3988                                 session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3989                         } else {
3990                                 //none
3991                         }
3992
3993                         //data state is HTTP_START
3994                         if (session_data_ptr->data_state == HTTP_START) {
3995                                 //set return status
3996                                 status = SORRYSERVER_RECV;
3997                         }
3998                         //data state is not HTTP_START
3999                         else {
4000                                 //set return status
4001                                 status = CLIENT_CONNECTION_CHECK;
4002                         }
4003                 }
4004
4005                 //set last status
4006                 session_data_ptr->last_status = status;
4007         } catch (int e) {
4008                 /*-------- DEBUG LOG --------*/
4009                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4010                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4011                                                 "handle_sorryserver_recv() : catch exception e = %d. thread id : %d.");
4012                         formatter % e % boost::this_thread::get_id();
4013                         putLogDebug(600119, formatter.str(), __FILE__, __LINE__);
4014                 }
4015                 /*------DEBUG LOG END------*/
4016
4017                 //set return status
4018                 status = FINALIZE;
4019         } catch (const boost::bad_lexical_cast &) {
4020                 std::cerr << "protocol_module_ip::handle_sorryserver_recv() : exception : " <<  "Content_Length field's value is invalid." << std::endl;
4021                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_recv() : "
4022                                         "Content_Length field's value is invalid. thread id : %d.");
4023                 formatter % boost::this_thread::get_id();
4024                 putLogError(600077, formatter.str(), __FILE__, __LINE__);
4025
4026                 //set return status
4027                 status = FINALIZE;
4028         } catch (const std::exception &ex) {
4029                 std::cerr << "protocol_module_ip::handle_sorryserver_recv() : exception : error = " << ex.what() << "." << std::endl;
4030                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4031                                         "handle_sorryserver_recv() : exception : error = %s. thread id : %d.");
4032                 formatter % ex.what() % boost::this_thread::get_id();
4033                 putLogError(600078, formatter.str(), __FILE__, __LINE__);
4034
4035                 //set return status
4036                 status = FINALIZE;
4037         } catch (...) {
4038                 std::cerr << "protocol_module_ip::handle_sorryserver_recv() : Unknown exception." << std::endl;
4039                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
4040                                         "protocol_module_ip::handle_sorryserver_recv() : "
4041                                         "Unknown exception. thread id : %d.");
4042                 formatter % boost::this_thread::get_id();
4043                 putLogError(600079, formatter.str(), __FILE__, __LINE__);
4044
4045                 //set return status
4046                 status = FINALIZE;
4047         }
4048
4049         /*-------- DEBUG LOG --------*/
4050         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4051                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4052                                         "handle_sorryserver_recv(const boost::thread::id thread_id, "
4053                                         "const boost::asio::ip::tcp::endpoint& sorry_endpoint, "
4054                                         "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
4055                                         "const size_t recvlen) : return_value = %d. thread id : %d.");
4056                 formatter % FINALIZE % boost::this_thread::get_id();
4057                 putLogDebug(600120, formatter.str(), __FILE__, __LINE__);
4058         }
4059         /*------DEBUG LOG END------*/
4060
4061         return status;
4062
4063 }
4064
4065 //! called from UPSTREAM thread. make module original message.
4066 //! @param[in]    downstream thread id.
4067 //! @return     session use EVENT mode
4068 protocol_module_base::EVENT_TAG protocol_module_ip::handle_response_send_inform(
4069         const boost::thread::id thread_id)
4070 {
4071         /*-------- DEBUG LOG --------*/
4072         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4073                 boost::format formatter("in/out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4074                                         "handle_response_send_inform(const boost::thread::id thread_id) : "
4075                                         "return_value = %d. thread id : %d.");
4076                 formatter % STOP % boost::this_thread::get_id();
4077                 putLogDebug(600121, formatter.str(), __FILE__, __LINE__);
4078         }
4079         /*------DEBUG LOG END------*/
4080
4081         return STOP;
4082 }
4083
4084 //! called from after client connection check. use TCP/IP only. create client send message.
4085 //! @param[in]    downstream thread id
4086 //! @param[out]    send buffer reference
4087 //! @param[out]    send data length
4088 //! @return     session use EVENT mode
4089 protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_connection_check(
4090         const boost::thread::id thread_id, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen)
4091 {
4092         /*-------- DEBUG LOG --------*/
4093         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4094                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4095                                         "handle_client_connection_check(const boost::thread::id thread_id, "
4096                                         "boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t& datalen) : "
4097                                         "thread_id = %d.");
4098                 formatter % thread_id;
4099                 putLogDebug(600122, formatter.str(), __FILE__, __LINE__);
4100         }
4101         /*------DEBUG LOG END------*/
4102
4103         EVENT_TAG status = FINALIZE;
4104         thread_data_ptr session_data_ptr;
4105         size_t send_possible_size = 0;
4106
4107         try {
4108                 {
4109                         boost::mutex::scoped_lock sclock(session_thread_data_map_mutex);
4110
4111                         session_thread_data_map_it session_thread_it = session_thread_data_map.find(thread_id);
4112                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
4113                                 boost::format formatter("Invalid thread id. thread id : %d.");
4114                                 formatter % boost::this_thread::get_id();
4115                                 putLogError(600080, formatter.str(), __FILE__, __LINE__);
4116                                 throw - 1;
4117                         }
4118
4119                         session_data_ptr = session_thread_it->second;
4120                 }
4121
4122                 //data state is HTTP_HEADER
4123                 if (session_data_ptr->data_state == HTTP_HEADER) {
4124                         //set data HTTP_BODY
4125                         session_data_ptr->data_state = HTTP_BODY;
4126                 }
4127
4128                 //set send possible data size
4129                 send_possible_size = std::min(std::min(sendbuffer.size(), session_data_ptr->current_message_rest_size),
4130                                               session_data_ptr->data_length
4131                                              );
4132                 //set send data size
4133                 datalen = send_possible_size;
4134
4135                 /*-------- DEBUG LOG --------*/
4136                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4137                         std::string datadump;
4138                         dump_memory(session_data_ptr->data_buffer + session_data_ptr->data_offset, send_possible_size, datadump);
4139
4140                         boost::format formatter(
4141                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4142                                 "handle_client_connection_check() : before memcpy (data dump) : "
4143                                 "data begin = %d, data_size = %d, data = %s");
4144                         formatter % session_data_ptr->data_offset % send_possible_size % datadump;
4145                         putLogDebug(600123, formatter.str(), __FILE__, __LINE__);
4146                 }
4147                 /*------DEBUG LOG END------*/
4148
4149                 //copy send possible data to sendbuffer
4150                 memcpy(sendbuffer.data(), session_data_ptr->data_buffer + session_data_ptr->data_offset,
4151                        send_possible_size);
4152
4153                 /*-------- DEBUG LOG --------*/
4154                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4155                         std::string datadump;
4156                         dump_memory(sendbuffer.data(), send_possible_size, datadump);
4157
4158                         boost::format formatter(
4159                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4160                                 "handle_client_connection_check() : after memcpy (data dump) : "
4161                                 "data begin = 0, data_size = %d, data = %s");
4162                         formatter % send_possible_size % datadump;
4163                         putLogDebug(600124, formatter.str(), __FILE__, __LINE__);
4164                 }
4165                 /*------DEBUG LOG END------*/
4166
4167                 //set current message rest size
4168                 session_data_ptr->current_message_rest_size -= send_possible_size;
4169
4170                 //set buffer's position
4171                 session_data_ptr->data_offset += send_possible_size;
4172                 session_data_ptr->data_length -= send_possible_size;
4173
4174                 //current message rest size is 0
4175                 if (session_data_ptr->current_message_rest_size == 0) {
4176                         boost::mutex::scoped_lock lock(session_data_mutex);
4177                         time_t now;
4178                         time(&now);
4179                         boost::asio::ip::tcp::endpoint init_endpoint;
4180
4181                         //write session data to session table
4182                         ip_data_processor->write_session_data(session_data_ptr->ip_hash,
4183                                                               init_endpoint,
4184                                                               now);
4185
4186                 }
4187
4188                 //set return status
4189                 status = CLIENT_SEND;
4190
4191                 //set last status
4192                 session_data_ptr->last_status = status;
4193         } catch (int e) {
4194                 /*-------- DEBUG LOG --------*/
4195                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4196                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4197                                                 "handle_client_connection_check() : catch exception e = %d. thread id : %d.");
4198                         formatter % e % boost::this_thread::get_id();
4199                         putLogDebug(600125, formatter.str(), __FILE__, __LINE__);
4200                 }
4201                 /*------DEBUG LOG END------*/
4202
4203                 //set return status
4204                 status = FINALIZE;
4205         } catch (const std::exception &ex) {
4206                 std::cerr << "protocol_module_ip::handle_client_connection_check() : exception : error = " << ex.what() << "." << std::endl;
4207                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4208                                         "handle_client_connection_check() : exception : error = %s. thread id : %d.");
4209                 formatter % ex.what() % boost::this_thread::get_id();
4210                 putLogError(600081, formatter.str(), __FILE__, __LINE__);
4211
4212                 //set return status
4213                 status = FINALIZE;
4214         } catch (...) {
4215                 std::cerr << "protocol_module_ip::handle_client_connection_check() : Unknown exception." << std::endl;
4216                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4217                                         "handle_client_connection_check() : Unknown exception. thread id : %d.");
4218                 formatter % boost::this_thread::get_id();
4219                 putLogError(600082, formatter.str(), __FILE__, __LINE__);
4220
4221                 //set return status
4222                 status = FINALIZE;
4223         }
4224
4225         /*-------- DEBUG LOG --------*/
4226         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4227                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4228                                         "handle_client_connection_check(const boost::thread::id thread_id, "
4229                                         "boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t& datalen) : return_value = %d. thread id : %d.");
4230                 formatter % status % boost::this_thread::get_id();
4231                 putLogDebug(600126, formatter.str(), __FILE__, __LINE__);
4232         }
4233         /*------DEBUG LOG END------*/
4234
4235         return status;
4236 }
4237
4238 //! called from after client select. use UDP only
4239 //! @param[in]    downstream thread id
4240 //!    @param[in]    client udp endpoint
4241 //! @param[out]    send buffer reference
4242 //! @param[out]    send data length
4243 //! @return     session use EVENT mode
4244 protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_select(
4245         const boost::thread::id thread_id, boost::asio::ip::udp::endpoint &cl_endpoint, boost::array < char,
4246         MAX_BUFFER_SIZE > & sendbuffer, size_t &datalen)
4247 {
4248         /*-------- DEBUG LOG --------*/
4249         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4250                 boost::format formatter("in/out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4251                                         "handle_client_select(const boost::thread::id thread_id, "
4252                                         "boost::asio::ip::udp::endpoint& cl_endpoint, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
4253                                         "const size_t& datalen) : "
4254                                         "return_value = %d. thread id : %d.");
4255                 formatter % STOP % boost::this_thread::get_id();
4256                 putLogDebug(600127, formatter.str(), __FILE__, __LINE__);
4257         }
4258         /*------DEBUG LOG END------*/
4259         return STOP;
4260 }
4261
4262 //!    called from after client send
4263 //!    @param[in]    downstream thread id
4264 //! @return     session use EVENT mode
4265 protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_send(
4266         const boost::thread::id thread_id)
4267 {
4268         /*-------- DEBUG LOG --------*/
4269         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4270                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4271                                         "handle_client_send(const boost::thread::id thread_id) : thread_id = %d.");
4272                 formatter % thread_id;
4273                 putLogDebug(600128, formatter.str(), __FILE__, __LINE__);
4274         }
4275         /*------DEBUG LOG END------*/
4276
4277         EVENT_TAG status = FINALIZE;
4278         size_t http_header_all_offset        = 0;
4279         size_t http_header_all_len        = 0;
4280         size_t http_header_content_length_offset = 0;
4281         size_t http_header_content_length_len    = 0;
4282         const size_t CR_LF_LEN             = 2;
4283         const size_t CR_LF_CR_LF_LEN        = 4;
4284         int content_length_value        = 0;
4285
4286         std::string content_length;
4287         cmatch regex_ret;
4288         cregex content_length_regex = icase("Content-Length") >> ":" >> *~_d >> (s1 = +_d) >> *~_d;
4289
4290
4291         bool find_ret = false;
4292         http_utility::CHECK_RESULT_TAG check_ret;
4293
4294         thread_data_ptr session_data_ptr;
4295         session_thread_data_map_it session_thread_it;
4296
4297         try {
4298                 {
4299                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
4300
4301                         //thread id check
4302                         session_thread_it = session_thread_data_map.find(thread_id);
4303                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
4304                                 boost::format formatter("Invalid thread id. thread id : %d.");
4305                                 formatter % boost::this_thread::get_id();
4306                                 putLogError(600083, formatter.str(), __FILE__, __LINE__);
4307                                 throw - 1;
4308                         }
4309
4310                         session_data_ptr = session_thread_it->second;
4311                 }
4312
4313                 //current_message_rest_size > 0
4314                 if (session_data_ptr->current_message_rest_size > 0) {
4315                         //data size > 0
4316                         if (session_data_ptr->data_length > 0) {
4317                                 //set return status
4318                                 status = CLIENT_CONNECTION_CHECK;
4319                         }
4320                         //data size is 0
4321                         else {
4322                                 //data offset is 0
4323                                 session_data_ptr->data_offset = 0;
4324
4325                                 //set return status
4326                                 status = REALSERVER_RECV;
4327                         }
4328                 }
4329                 //current_message_rest_size is 0
4330                 else {
4331                         //data size > 0
4332                         if (session_data_ptr->data_length > 0) {
4333                                 //data state is HTTP_BODY
4334                                 if (session_data_ptr->data_state == HTTP_BODY) {
4335                                         //search whole http header, get whole http header's offset and length
4336                                         find_ret = http_utility::find_http_header_all(session_data_ptr->data_buffer + session_data_ptr->data_offset,
4337                                                         session_data_ptr->data_length,
4338                                                         http_header_all_offset,
4339                                                         http_header_all_len
4340                                                                                      );
4341
4342                                         /*-------- DEBUG LOG --------*/
4343                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4344                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4345                                                                         "handle_client_send() : call find_http_header_all : "
4346                                                                         "return_value = %d. thread id : %d.");
4347                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
4348                                                 putLogDebug(600129, formatter.str(), __FILE__, __LINE__);
4349                                         }
4350                                         /*------DEBUG LOG END------*/
4351
4352                                         //search http header result is NG
4353                                         if (!find_ret) {
4354                                                 //set data state HTTP_START
4355                                                 session_data_ptr->data_state = HTTP_START;
4356
4357                                                 //set return status
4358                                                 status = REALSERVER_RECV;
4359                                         }
4360                                         //search http header result is OK
4361                                         else {
4362                                                 //check http version and status code
4363                                                 check_ret = http_utility::check_http_version_and_status_code(session_data_ptr->data_buffer + session_data_ptr->data_offset,
4364                                                                 session_data_ptr->data_length);
4365
4366                                                 /*-------- DEBUG LOG --------*/
4367                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4368                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4369                                                                                 "handle_client_send() : call check_http_version_and_status_code : "
4370                                                                                 "return_value = %d. thread id : %d.");
4371                                                         formatter % check_ret % boost::this_thread::get_id();
4372                                                         putLogDebug(600130, formatter.str(), __FILE__, __LINE__);
4373                                                 }
4374                                                 /*------DEBUG LOG END------*/
4375
4376                                                 //check version and status code result is NG
4377                                                 if (check_ret == http_utility::CHECK_NG) {
4378                                                         //set current message rest size
4379                                                         session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
4380
4381                                                         //set data state UNKNOWN
4382                                                         session_data_ptr->data_state = UNKNOWN;
4383                                                 }
4384                                                 //check version and status code result is OK
4385                                                 else {
4386                                                         //search Content_Length header
4387                                                         find_ret = http_utility::find_http_header_content_length(session_data_ptr->data_buffer + session_data_ptr->data_offset,
4388                                                                         session_data_ptr->data_length,
4389                                                                         http_header_content_length_offset,
4390                                                                         http_header_content_length_len);
4391
4392                                                         /*-------- DEBUG LOG --------*/
4393                                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4394                                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4395                                                                                         "handle_client_send() : call find_http_header_content_length : "
4396                                                                                         "return_value = %d. thread id : %d.");
4397                                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
4398                                                                 putLogDebug(600131, formatter.str(), __FILE__, __LINE__);
4399                                                         }
4400                                                         /*------DEBUG LOG END------*/
4401
4402                                                         //search Content_Length result is OK
4403                                                         if (find_ret) {
4404                                                                 content_length.assign(session_data_ptr->data_buffer + session_data_ptr->data_offset + http_header_content_length_offset,
4405                                                                                       http_header_content_length_len);
4406                                                                 find_ret = regex_search(content_length.c_str(), regex_ret, content_length_regex);
4407
4408                                                                 //"content-length: ddd\r\n"
4409                                                                 if (find_ret) {
4410                                                                         content_length = content_length.substr(
4411                                                                                                  regex_ret.position(1),
4412                                                                                                  regex_ret.length(1));
4413
4414                                                                         //set content length value
4415                                                                         content_length_value = boost::lexical_cast<int>(content_length);
4416                                                                 }
4417
4418                                                                 //http_header context is "\r\n\r\n" only
4419                                                                 if (http_header_all_len == 0) {
4420                                                                         //set current message rest size
4421                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + content_length_value + CR_LF_LEN;
4422                                                                 } else {
4423                                                                         //set current message rest size
4424                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + content_length_value + CR_LF_CR_LF_LEN;
4425                                                                 }
4426                                                         }
4427                                                         //search Content_Length result is OK
4428                                                         else {
4429                                                                 //http_header context is "\r\n\r\n" only
4430                                                                 if (http_header_all_len == 0) {
4431                                                                         //set current message rest size
4432                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + CR_LF_LEN;
4433                                                                 } else {
4434                                                                         //set current message rest size
4435                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + CR_LF_CR_LF_LEN;
4436                                                                 }
4437
4438                                                         }
4439
4440                                                         //set data state HTTP_HEADER
4441                                                         session_data_ptr->data_state = HTTP_HEADER;
4442                                                 }
4443
4444                                                 //set return status
4445                                                 status = CLIENT_CONNECTION_CHECK;
4446                                         }
4447                                 }
4448                                 //data state is UNKNOWN
4449                                 else if (session_data_ptr->data_state == UNKNOWN) {
4450                                         //set return status
4451                                         status = CLIENT_CONNECTION_CHECK;
4452                                 }
4453                         }
4454                         //data size is 0
4455                         else {
4456                                 //data state is HTTP_BODY
4457                                 if (session_data_ptr->data_state == HTTP_BODY) {
4458                                         //set data state HTTP_START
4459                                         session_data_ptr->data_state = HTTP_START;
4460                                 }
4461
4462                                 //set data offset 0
4463                                 session_data_ptr->data_offset = 0;
4464
4465                                 //set return status
4466                                 status = REALSERVER_RECV;
4467                         }
4468                 }
4469
4470                 //switch flag is on and status is REALSERVER_RECV
4471                 if (session_data_ptr->switch_flag == SWITCH_FLAG_ON
4472                     && status == REALSERVER_RECV) {
4473                         //set return status
4474                         status = CLIENT_DISCONNECT;
4475                 }
4476                 //sorry flag is on and and status is REALSERVER_RECV
4477                 else if (session_data_ptr->sorry_flag == SORRY_FLAG_ON
4478                          && status == REALSERVER_RECV) {
4479                         //set return status
4480                         status = SORRYSERVER_RECV;
4481                 } else {
4482                         //none
4483                 }
4484
4485                 //set last status
4486                 session_data_ptr->last_status = status;
4487         } catch (int e) {
4488                 /*-------- DEBUG LOG --------*/
4489                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4490                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4491                                                 "handle_client_send() : catch exception e = %d. thread id : %d.");
4492                         formatter % e % boost::this_thread::get_id();
4493                         putLogDebug(600132, formatter.str(), __FILE__, __LINE__);
4494                 }
4495                 /*------DEBUG LOG END------*/
4496
4497                 //set last status
4498                 status = FINALIZE;
4499         } catch (const boost::bad_lexical_cast &) {
4500                 std::cerr << "protocol_module_ip::handle_client_send() : exception : " <<  "Content_Length field's value is invalid." << std::endl;
4501                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_send() : "
4502                                         "Content_Length field's value is invalid. thread id : %d.");
4503                 formatter % boost::this_thread::get_id();
4504                 putLogError(600084, formatter.str(), __FILE__, __LINE__);
4505
4506                 //set last status
4507                 status = FINALIZE;
4508         } catch (const std::exception &ex) {
4509                 std::cerr << "protocol_module_ip::handle_client_send() : exception : error = " << ex.what() << "." << std::endl;
4510                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4511                                         "handle_client_send() : exception : error = %s. thread id : %d.");
4512                 formatter % ex.what() % boost::this_thread::get_id();
4513                 putLogError(600085, formatter.str(), __FILE__, __LINE__);
4514
4515                 //set last status
4516                 status = FINALIZE;
4517         } catch (...) {
4518                 std::cerr << "protocol_module_ip::handle_client_send() : Unknown exception." << std::endl;
4519                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
4520                                         "protocol_module_ip::handle_client_send() : "
4521                                         "Unknown exception. thread id : %d.");
4522                 formatter % boost::this_thread::get_id();
4523                 putLogError(600086, formatter.str(), __FILE__, __LINE__);
4524
4525                 //set last status
4526                 status = FINALIZE;
4527         }
4528
4529         /*-------- DEBUG LOG --------*/
4530         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4531                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4532                                         "handle_client_send(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
4533                 formatter % status % boost::this_thread::get_id();
4534                 putLogDebug(600133, formatter.str(), __FILE__, __LINE__);
4535         }
4536         /*------DEBUG LOG END------*/
4537
4538         return status;
4539 }
4540
4541 //! call from client disconnect event. use upstream thread and downstream thread.
4542 //! @param[in]    upstream and downstream thread id( check! one thread one event! )
4543 //! @return     session use EVENT mode
4544 protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_disconnect(
4545         const boost::thread::id thread_id)
4546 {
4547         /*-------- DEBUG LOG --------*/
4548         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4549                 boost::format formatter("in/out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4550                                         "handle_client_disconnect(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
4551                 formatter % FINALIZE % boost::this_thread::get_id();
4552                 putLogDebug(600134, formatter.str(), __FILE__, __LINE__);
4553         }
4554         /*------DEBUG LOG END------*/
4555         return FINALIZE;
4556 }
4557
4558 //! call from sorry mode event. use upstream thread and downstream thread
4559 //! @param[in]    upstream and downstream thread id( check! one thread one event and first time call pattern )
4560 //! @return     session use EVENT mode
4561 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorry_enable(
4562         const boost::thread::id thread_id)
4563 {
4564         /*-------- DEBUG LOG --------*/
4565         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4566                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4567                                         "handle_sorry_enable(const boost::thread::id thread_id) : thread_id = %d.");
4568                 formatter % boost::this_thread::get_id();
4569                 putLogDebug(600135, formatter.str(), __FILE__, __LINE__);
4570         }
4571         /*------DEBUG LOG END------*/
4572
4573         EVENT_TAG status = FINALIZE;
4574         thread_data_ptr session_data_ptr;
4575
4576         try {
4577                 {
4578                         boost::mutex::scoped_lock sclock(session_thread_data_map_mutex);
4579
4580                         session_thread_data_map_it session_thread_it = session_thread_data_map.find(thread_id);
4581                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
4582                                 boost::format formatter("Invalid thread id. thread id : %d.");
4583                                 formatter % boost::this_thread::get_id();
4584                                 putLogError(600087, formatter.str(), __FILE__, __LINE__);
4585                                 throw - 1;
4586                         }
4587
4588                         session_data_ptr = session_thread_it->second;
4589                 }
4590
4591
4592                 //up thread
4593                 if (session_data_ptr->thread_division == THREAD_DIVISION_UP_STREAM) {
4594                         //accept_end_flag is off
4595                         if (session_data_ptr->accept_end_flag == ACCEPT_END_FLAG_OFF) {
4596                                 //set return status
4597                                 status = ACCEPT;
4598                         }
4599                         //accept_end_flag is on
4600                         else {
4601                                 //sorry flag is on
4602                                 if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
4603                                         //data state is HTTP_START or HTTP_HEADER
4604                                         if (session_data_ptr->data_state == HTTP_START
4605                                             || session_data_ptr->data_state == HTTP_HEADER) {
4606                                                 //set switch flag on
4607                                                 session_data_ptr->switch_flag = SWITCH_FLAG_ON;
4608
4609                                                 /*-------- DEBUG LOG --------*/
4610                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4611                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4612                                                                                 "handle_sorry_enable(const boost::thread::id thread_id) : SWITCH_FLAG_ON. thread id : %d.");
4613                                                         formatter % boost::this_thread::get_id();
4614                                                         putLogDebug(600136, formatter.str(), __FILE__, __LINE__);
4615                                                 }
4616                                                 /*------DEBUG LOG END------*/
4617
4618                                                 //set return status
4619                                                 status = SORRYSERVER_DISCONNECT;
4620                                         }
4621                                         //data state is HTTP_BODY or UNKNOWN
4622                                         else {
4623                                                 //set return status
4624                                                 status = session_data_ptr->last_status;
4625                                         }
4626                                 }
4627                                 //sorry flag is off
4628                                 else {
4629                                         //data state is HTTP_START or HTTP_HEADER
4630                                         if (session_data_ptr->data_state == HTTP_START
4631                                             || session_data_ptr->data_state == HTTP_HEADER) {
4632                                                 //set switch flag on
4633                                                 session_data_ptr->switch_flag = SWITCH_FLAG_ON;
4634
4635                                                 /*-------- DEBUG LOG --------*/
4636                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4637                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4638                                                                                 "handle_sorry_enable(const boost::thread::id thread_id) : SWITCH_FLAG_ON. thread id : %d.");
4639                                                         formatter % boost::this_thread::get_id();
4640                                                         putLogDebug(600137, formatter.str(), __FILE__, __LINE__);
4641                                                 }
4642                                                 /*------DEBUG LOG END------*/
4643                                         }
4644                                         //data state is HTTP_BODY or UNKNOWN
4645                                         else {
4646                                                 //set end flag on
4647                                                 session_data_ptr->end_flag = END_FLAG_ON;
4648
4649                                                 /*-------- DEBUG LOG --------*/
4650                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4651                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4652                                                                                 "handle_sorry_enable(const boost::thread::id thread_id) : END_FLAG_ON. thread id : %d.");
4653                                                         formatter % boost::this_thread::get_id();
4654                                                         putLogDebug(600138, formatter.str(), __FILE__, __LINE__);
4655                                                 }
4656                                                 /*------DEBUG LOG END------*/
4657                                         }
4658
4659                                         //set return status
4660                                         status = REALSERVER_DISCONNECT;
4661                                 }
4662                         }
4663                 }
4664                 //down thread
4665                 else {
4666                         //sorry flag is on
4667                         if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
4668                                 //set return status
4669                                 status = session_data_ptr->last_status;
4670                         }
4671                         //sorry flag is off
4672                         else {
4673                                 //data state is HTTP_START and data size is 0
4674                                 if (session_data_ptr->data_state == HTTP_START
4675                                     && session_data_ptr->data_length == 0) {
4676                                         //set return status
4677                                         status = SORRYSERVER_RECV;
4678                                 }
4679                                 //data state is HTTP_START and data size > 0
4680                                 else if (session_data_ptr->data_state == HTTP_START
4681                                          && session_data_ptr->data_length > 0) {
4682                                         //set return status
4683                                         status = REALSERVER_DISCONNECT;
4684                                 }
4685                                 //data state is HTTP_HEADER or HTTP_BODY
4686                                 else if (session_data_ptr->data_state == HTTP_HEADER
4687                                          || session_data_ptr->data_state == HTTP_BODY) {
4688                                         //set switch flag on
4689                                         session_data_ptr->switch_flag = SWITCH_FLAG_ON;
4690
4691                                         /*-------- DEBUG LOG --------*/
4692                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4693                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4694                                                                         "handle_sorry_enable(const boost::thread::id thread_id) : SWITCH_FLAG_ON. thread id : %d.");
4695                                                 formatter % boost::this_thread::get_id();
4696                                                 putLogDebug(600139, formatter.str(), __FILE__, __LINE__);
4697                                         }
4698                                         /*------DEBUG LOG END------*/
4699
4700                                         //set return status
4701                                         status = session_data_ptr->last_status;
4702                                 }
4703                                 //other
4704                                 else {
4705                                         //set return status
4706                                         status = REALSERVER_DISCONNECT;
4707                                 }
4708                         }
4709                 }
4710
4711                 //set sorry flag on
4712                 session_data_ptr->sorry_flag = SORRY_FLAG_ON;
4713
4714                 /*-------- DEBUG LOG --------*/
4715                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4716                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4717                                                 "handle_sorry_enable(const boost::thread::id thread_id) : SORRY_FLAG_ON. thread id : %d.");
4718                         formatter % boost::this_thread::get_id();
4719                         putLogDebug(600140, formatter.str(), __FILE__, __LINE__);
4720                 }
4721                 /*------DEBUG LOG END------*/
4722
4723                 //set last status
4724                 session_data_ptr->last_status = status;
4725
4726         } catch (int e) {
4727                 /*-------- DEBUG LOG --------*/
4728                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4729                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4730                                                 "handle_sorry_enable() : catch exception e = %d. thread id : %d.");
4731                         formatter % e % boost::this_thread::get_id();
4732                         putLogDebug(600141, formatter.str(), __FILE__, __LINE__);
4733                 }
4734                 /*------DEBUG LOG END------*/
4735
4736                 //set return status
4737                 status = FINALIZE;
4738         } catch (std::exception &ex) {
4739                 std::cerr << "protocol_module_ip::handle_sorry_enable() : exception : error = " << ex.what() << "." << std::endl;
4740                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4741                                         "handle_sorry_enable() : exception : error = %s. thread id : %d.");
4742                 formatter % ex.what() % boost::this_thread::get_id();
4743                 putLogError(600088, formatter.str(), __FILE__, __LINE__);
4744
4745                 //set return status
4746                 status = FINALIZE;
4747         } catch (...) {
4748                 std::cerr << "protocol_module_ip::handle_sorry_enable() : Unknown exception." << std::endl;
4749                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
4750                                         "protocol_module_ip::handle_sorry_enable() : "
4751                                         "Unknown exception. thread id : %d.");
4752                 formatter % boost::this_thread::get_id();
4753                 putLogError(600089, formatter.str(), __FILE__, __LINE__);
4754
4755                 //set return status
4756                 status = FINALIZE;
4757         }
4758
4759         /*-------- DEBUG LOG --------*/
4760         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4761                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4762                                         "handle_sorry_enable(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
4763                 formatter % status % boost::this_thread::get_id();
4764                 putLogDebug(600142, formatter.str(), __FILE__, __LINE__);
4765         }
4766         /*------DEBUG LOG END------*/
4767
4768         return status;
4769 }
4770
4771 //! call from sorry mode disable. use upstream thread and downstream thread.
4772 //! @param[in]    upstream and downstream thread id( check! one thread one event )
4773 //! @return     session use EVENT mode
4774 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorry_disable(
4775         const boost::thread::id thread_id)
4776 {
4777         /*-------- DEBUG LOG --------*/
4778         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4779                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4780                                         "handle_sorry_disable(const boost::thread::id thread_id) : thread_id = %d.");
4781                 formatter % boost::this_thread::get_id();
4782                 putLogDebug(600143, formatter.str(), __FILE__, __LINE__);
4783         }
4784         /*------DEBUG LOG END------*/
4785
4786         EVENT_TAG status = FINALIZE;
4787         thread_data_ptr session_data_ptr;
4788
4789         try {
4790                 {
4791                         boost::mutex::scoped_lock sclock(session_thread_data_map_mutex);
4792
4793                         session_thread_data_map_it session_thread_it = session_thread_data_map.find(thread_id);
4794                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
4795                                 boost::format formatter("Invalid thread id. thread id : %d.");
4796                                 formatter % boost::this_thread::get_id();
4797                                 putLogError(600090, formatter.str(), __FILE__, __LINE__);
4798                                 throw - 1;
4799                         }
4800
4801                         session_data_ptr = session_thread_it->second;
4802                 }
4803
4804                 //up thread
4805                 if (session_data_ptr->thread_division == THREAD_DIVISION_UP_STREAM) {
4806                         //accept_end_flag is off
4807                         if (session_data_ptr->accept_end_flag == ACCEPT_END_FLAG_OFF) {
4808                                 //set return status
4809                                 status = ACCEPT;
4810                         }
4811                         //accept_end_flag is on
4812                         else {
4813                                 //sorry flag is on
4814                                 if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
4815                                         ///data state is HTTP_START or HTTP_HEADER
4816                                         if (session_data_ptr->data_state == HTTP_START
4817                                             || session_data_ptr->data_state == HTTP_HEADER) {
4818                                                 //set switch flag on
4819                                                 session_data_ptr->switch_flag = SWITCH_FLAG_ON;
4820
4821                                                 /*-------- DEBUG LOG --------*/
4822                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4823                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4824                                                                                 "handle_sorry_disable(const boost::thread::id thread_id) : SWITCH_FLAG_ON. thread id : %d.");
4825                                                         formatter % boost::this_thread::get_id();
4826                                                         putLogDebug(600144, formatter.str(), __FILE__, __LINE__);
4827                                                 }
4828                                                 /*------DEBUG LOG END------*/
4829
4830                                         }
4831                                         //data state is HTTP_BODY or UNKNOWN
4832                                         else {
4833                                                 //set end flag on
4834                                                 session_data_ptr->end_flag = END_FLAG_ON;
4835
4836                                                 /*-------- DEBUG LOG --------*/
4837                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4838                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4839                                                                                 "handle_sorry_disable(const boost::thread::id thread_id) : END_FLAG_ON. thread id : %d.");
4840                                                         formatter % boost::this_thread::get_id();
4841                                                         putLogDebug(600145, formatter.str(), __FILE__, __LINE__);
4842                                                 }
4843                                                 /*------DEBUG LOG END------*/
4844                                         }
4845
4846                                         //set return status
4847                                         status = SORRYSERVER_DISCONNECT;
4848
4849                                 }
4850                                 //sorry flag is off
4851                                 else {
4852                                         //data state is HTTP_START or HTTP_HEADER
4853                                         if (session_data_ptr->data_state == HTTP_START
4854                                             || session_data_ptr->data_state == HTTP_HEADER) {
4855                                                 //set switch flag on
4856                                                 session_data_ptr->switch_flag = SWITCH_FLAG_ON;
4857
4858                                                 /*-------- DEBUG LOG --------*/
4859                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4860                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4861                                                                                 "handle_sorry_disable(const boost::thread::id thread_id) : SWITCH_FLAG_ON. thread id : %d.");
4862                                                         formatter % boost::this_thread::get_id();
4863                                                         putLogDebug(600146, formatter.str(), __FILE__, __LINE__);
4864                                                 }
4865                                                 /*------DEBUG LOG END------*/
4866
4867                                                 //set return status
4868                                                 status = REALSERVER_DISCONNECT;
4869                                         }
4870                                         //data state is HTTP_BODY or UNKNOWN
4871                                         else {
4872                                                 //set return status
4873                                                 status = session_data_ptr->last_status;
4874                                         }
4875                                 }
4876                         }
4877                 }
4878                 //down thread
4879                 else {
4880                         //sorry flag is off
4881                         if (session_data_ptr->sorry_flag == SORRY_FLAG_OFF) {
4882                                 //set return status
4883                                 status = session_data_ptr->last_status;
4884                         }
4885                         //sorry flag is on
4886                         else {
4887                                 //data state is HTTP_START and data size is 0
4888                                 if (session_data_ptr->data_state == HTTP_START
4889                                     && session_data_ptr->data_length == 0) {
4890                                         //set return status
4891                                         status = REALSERVER_RECV;
4892                                 }
4893                                 //data state is HTTP_START and data size > 0
4894                                 else if (session_data_ptr->data_state == HTTP_START
4895                                          && session_data_ptr->data_length > 0) {
4896                                         //set return status
4897                                         status = SORRYSERVER_DISCONNECT;
4898                                 }
4899                                 //data state is HTTP_HEADER or HTTP_BODY
4900                                 else if (session_data_ptr->data_state == HTTP_HEADER
4901                                          || session_data_ptr->data_state == HTTP_BODY) {
4902                                         //set switch flag on
4903                                         session_data_ptr->switch_flag = SWITCH_FLAG_ON;
4904
4905                                         /*-------- DEBUG LOG --------*/
4906                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4907                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4908                                                                         "handle_sorry_disable(const boost::thread::id thread_id) : SWITCH_FLAG_ON. thread id : %d.");
4909                                                 formatter % boost::this_thread::get_id();
4910                                                 putLogDebug(600147, formatter.str(), __FILE__, __LINE__);
4911                                         }
4912                                         /*------DEBUG LOG END------*/
4913
4914                                         //set return status
4915                                         status = session_data_ptr->last_status;
4916                                 }
4917                                 //other
4918                                 else {
4919                                         //set return status
4920                                         status = SORRYSERVER_DISCONNECT;
4921                                 }
4922                         }
4923                 }
4924
4925                 //set sorry flag off
4926                 session_data_ptr->sorry_flag = SORRY_FLAG_OFF;
4927
4928                 /*-------- DEBUG LOG --------*/
4929                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4930                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4931                                                 "handle_sorry_disable(const boost::thread::id thread_id) : SORRY_FLAG_OFF. thread id : %d.");
4932                         formatter % boost::this_thread::get_id();
4933                         putLogDebug(600148, formatter.str(), __FILE__, __LINE__);
4934                 }
4935                 /*------DEBUG LOG END------*/
4936
4937                 //set last status
4938                 session_data_ptr->last_status = status;
4939         } catch (int e) {
4940                 /*-------- DEBUG LOG --------*/
4941                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4942                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4943                                                 "handle_sorry_disable() : catch exception e = %d. thread id : %d.");
4944                         formatter % e % boost::this_thread::get_id();
4945                         putLogDebug(600149, formatter.str(), __FILE__, __LINE__);
4946                 }
4947                 /*------DEBUG LOG END------*/
4948
4949                 //set last status
4950                 status = FINALIZE;
4951         } catch (std::exception &ex) {
4952                 std::cerr << "protocol_module_ip::handle_sorry_disable() : exception : error = " << ex.what() << "." << std::endl;
4953                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4954                                         "handle_sorry_disable() : exception : error = %s. thread id : %d.");
4955                 formatter % ex.what() % boost::this_thread::get_id();
4956                 putLogError(600091, formatter.str(), __FILE__, __LINE__);
4957
4958                 //set last status
4959                 status = FINALIZE;
4960         } catch (...) {
4961                 std::cerr << "protocol_module_ip::handle_sorry_disable() : Unknown exception." << std::endl;
4962                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
4963                                         "protocol_module_ip::handle_sorry_disable() : "
4964                                         "Unknown exception. thread id : %d.");
4965                 formatter % boost::this_thread::get_id();
4966                 putLogError(600092, formatter.str(), __FILE__, __LINE__);
4967
4968                 //set last status
4969                 status = FINALIZE;
4970         }
4971
4972         /*-------- DEBUG LOG --------*/
4973         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4974                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4975                                         "handle_sorry_disable(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
4976                 formatter % status % boost::this_thread::get_id();
4977                 putLogDebug(600150, formatter.str(), __FILE__, __LINE__);
4978         }
4979         /*------DEBUG LOG END------*/
4980
4981         return status;
4982 }
4983
4984 //! call from realserver disconnect. use upstream thread and downstream thread
4985 //! @param[in]    upstream and downstream thread id( check! one thread one event )
4986 //! @param[in]    disconnected realserver endpoint.
4987 //! @return     session use EVENT mode
4988 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_disconnect(
4989         const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &rs_endpoint)
4990 {
4991         /*-------- DEBUG LOG --------*/
4992         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4993                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4994                                         "handle_realserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint& rs_endpoint) : "
4995                                         "thread_id = %d, rs_endpoint = [%s]:%d.");
4996                 formatter % thread_id % rs_endpoint.address().to_string() % rs_endpoint.port();
4997                 putLogDebug(600151, formatter.str(), __FILE__, __LINE__);
4998         }
4999         /*------DEBUG LOG END------*/
5000
5001         EVENT_TAG status = FINALIZE;
5002         thread_data_ptr session_data_ptr;
5003
5004         try {
5005                 {
5006                         boost::mutex::scoped_lock sclock(session_thread_data_map_mutex);
5007
5008                         session_thread_data_map_it session_thread_it = session_thread_data_map.find(thread_id);
5009                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
5010                                 boost::format formatter("Invalid thread id. thread id : %d.");
5011                                 formatter % boost::this_thread::get_id();
5012                                 putLogError(600093, formatter.str(), __FILE__, __LINE__);
5013                                 throw - 1;
5014                         }
5015
5016                         session_data_ptr = session_thread_it->second;
5017                 }
5018
5019
5020                 //up thread
5021                 if (session_data_ptr->thread_division == THREAD_DIVISION_UP_STREAM) {
5022                         //end flag is on
5023                         if (session_data_ptr->end_flag == END_FLAG_ON) {
5024                                 //set return status
5025                                 status = CLIENT_RECV;
5026                         }
5027                         //end flag is off
5028                         else {
5029                                 //switch flag is on
5030                                 if (session_data_ptr->switch_flag == SWITCH_FLAG_ON) {
5031                                         //sorry flag is on
5032                                         if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
5033                                                 //set return status
5034                                                 status = SORRYSERVER_SELECT;
5035                                         }
5036                                         //sorry flag is off
5037                                         else {
5038                                                 //set return status
5039                                                 status = REALSERVER_SELECT;
5040                                         }
5041
5042                                         //set switch flag off
5043                                         session_data_ptr->switch_flag = SWITCH_FLAG_OFF;
5044
5045                                         /*-------- DEBUG LOG --------*/
5046                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5047                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5048                                                                         "handle_realserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &"                         "rs_endpoint) : SWITCH_FLAG_OFF. thread id : %d.");
5049                                                 formatter % boost::this_thread::get_id();
5050                                                 putLogDebug(600152, formatter.str(), __FILE__, __LINE__);
5051                                         }
5052                                         /*------DEBUG LOG END------*/
5053                                 }
5054                                 //switch flag is off
5055                                 else {
5056                                         //set return status
5057                                         status = CLIENT_RECV;
5058                                 }
5059                         }
5060                 }
5061                 //down thread
5062                 else {
5063                         //set return status
5064                         status = CLIENT_DISCONNECT;
5065                 }
5066
5067                 //set last status
5068                 session_data_ptr->last_status = status;
5069         } catch (int e) {
5070                 /*-------- DEBUG LOG --------*/
5071                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5072                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5073                                                 "handle_realserver_disconnect() : catch exception e = %d. thread id : %d.");
5074                         formatter % e % boost::this_thread::get_id();
5075                         putLogDebug(600153, formatter.str(), __FILE__, __LINE__);
5076                 }
5077                 /*------DEBUG LOG END------*/
5078
5079                 //set return status
5080                 status = FINALIZE;
5081         } catch (std::exception &ex) {
5082                 std::cerr << "protocol_module_ip::handle_realserver_disconnect() : exception : error = " << ex.what() << "." << std::endl;
5083                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5084                                         "handle_realserver_disconnect() : exception : error = %s. thread id : %d.");
5085                 formatter % ex.what() % boost::this_thread::get_id();
5086                 putLogError(600094, formatter.str(), __FILE__, __LINE__);
5087
5088                 //set return status
5089                 status = FINALIZE;
5090         } catch (...) {
5091                 std::cerr << "protocol_module_ip::handle_realserver_disconnect() : Unknown exception." << std::endl;
5092                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
5093                                         "protocol_module_ip::handle_realserver_disconnect() : "
5094                                         "Unknown exception. thread id : %d.");
5095                 formatter % boost::this_thread::get_id();
5096                 putLogError(600095, formatter.str(), __FILE__, __LINE__);
5097
5098                 //set return status
5099                 status = FINALIZE;
5100         }
5101
5102         /*-------- DEBUG LOG --------*/
5103         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5104                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5105                                         "handle_realserver_disconnect(const boost::thread::id thread_id, "
5106                                         "const boost::asio::ip::tcp::endpoint& rs_endpoint) : return_value = %d. thread id : %d.");
5107                 formatter % status % boost::this_thread::get_id();
5108                 putLogDebug(600154, formatter.str(), __FILE__, __LINE__);
5109         }
5110         /*------DEBUG LOG END------*/
5111
5112         return status;
5113 }
5114
5115 //! call from sorry server disconnect. use upstream thread and downstream thread
5116 //! @param[in]    upstream and downstream thread id( check! one thread one event )
5117 //! @param[in]    disconnect sorryserver endpoint
5118 //! @return        session use EVENT mode
5119 //! @return        session use EVENT mode
5120 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_disconnect(
5121         const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &sorry_endpoint)
5122 {
5123
5124         /*-------- DEBUG LOG --------*/
5125         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5126                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5127                                         "handle_sorryserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint& sorry_endpoint) : "
5128                                         "thread_id = %d, sorry_endpoint = [%s]:%d.");
5129                 formatter % thread_id % sorry_endpoint.address().to_string() % sorry_endpoint.port();
5130                 putLogDebug(600155, formatter.str(), __FILE__, __LINE__);
5131         }
5132         /*------DEBUG LOG END------*/
5133
5134         EVENT_TAG status = FINALIZE;
5135         thread_data_ptr session_data_ptr;
5136
5137         try {
5138                 {
5139                         boost::mutex::scoped_lock sclock(session_thread_data_map_mutex);
5140
5141                         session_thread_data_map_it session_thread_it = session_thread_data_map.find(thread_id);
5142                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
5143                                 boost::format formatter("Invalid thread id. thread id : %d.");
5144                                 formatter % boost::this_thread::get_id();
5145                                 putLogError(600096, formatter.str(), __FILE__, __LINE__);
5146                                 throw - 1;
5147                         }
5148
5149                         session_data_ptr = session_thread_it->second;
5150                 }
5151
5152                 //up thread
5153                 if (session_data_ptr->thread_division == THREAD_DIVISION_UP_STREAM) {
5154                         //end flag is on
5155                         if (session_data_ptr->end_flag == END_FLAG_ON) {
5156                                 //set return status
5157                                 status = CLIENT_RECV;
5158                         }
5159                         //end flag is off
5160                         else {
5161                                 //switch flag is on
5162                                 if (session_data_ptr->switch_flag == SWITCH_FLAG_ON) {
5163                                         //sorry flag is on
5164                                         if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
5165                                                 //set return status
5166                                                 status = SORRYSERVER_SELECT;
5167                                         }
5168                                         //sorry flag is off
5169                                         else {
5170                                                 //set return status
5171                                                 status = REALSERVER_SELECT;
5172                                         }
5173
5174                                         //set switch flag off
5175                                         session_data_ptr->switch_flag = SWITCH_FLAG_OFF;
5176
5177                                         /*-------- DEBUG LOG --------*/
5178                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5179                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5180                                                                         "handle_sorryserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &"                         "sorry_endpoint) : SWITCH_FLAG_OFF. thread id : %d.");
5181                                                 formatter % boost::this_thread::get_id();
5182                                                 putLogDebug(600156, formatter.str(), __FILE__, __LINE__);
5183                                         }
5184                                         /*------DEBUG LOG END------*/
5185
5186                                 }
5187                                 //switch flag is off
5188                                 else {
5189                                         //set return status
5190                                         status = CLIENT_RECV;
5191                                 }
5192                         }
5193                 }
5194                 //down thread
5195                 else {
5196                         //set return status
5197                         status = CLIENT_DISCONNECT;
5198                 }
5199
5200                 //set last status
5201                 session_data_ptr->last_status = status;
5202
5203         } catch (int e) {
5204                 /*-------- DEBUG LOG --------*/
5205                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5206                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5207                                                 "handle_sorryserver_disconnect() : catch exception e = %d. thread id : %d.");
5208                         formatter % e % boost::this_thread::get_id();
5209                         putLogDebug(600157, formatter.str(), __FILE__, __LINE__);
5210                 }
5211                 /*------DEBUG LOG END------*/
5212
5213                 //set return status
5214                 status = FINALIZE;
5215         }
5216
5217         catch (std::exception &ex) {
5218                 std::cerr << "protocol_module_ip::handle_sorryserver_disconnect() : exception : error = " << ex.what() << "." << std::endl;
5219                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5220                                         "handle_sorryserver_disconnect() : exception : error = %s. thread id : %d.");
5221                 formatter % ex.what() % boost::this_thread::get_id();
5222                 putLogError(600097, formatter.str(), __FILE__, __LINE__);
5223
5224                 //set return status
5225                 status = FINALIZE;
5226         } catch (...) {
5227                 std::cerr << "protocol_module_ip::handle_sorryserver_disconnect() : Unknown exception." << std::endl;
5228                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
5229                                         "protocol_module_ip::handle_sorryserver_disconnect() : "
5230                                         "Unknown exception. thread id : %d.");
5231                 formatter % boost::this_thread::get_id();
5232                 putLogError(600098, formatter.str(), __FILE__, __LINE__);
5233
5234                 //set return status
5235                 status = FINALIZE;
5236         }
5237
5238         /*-------- DEBUG LOG --------*/
5239         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5240                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5241                                         "handle_sorryserver_disconnect(const boost::thread::id thread_id, "
5242                                         "const boost::asio::ip::tcp::endpoint& sorry_endpoint) : return_value = %d. thread id : %d.");
5243                 formatter % status % boost::this_thread::get_id();
5244                 putLogDebug(600158, formatter.str(), __FILE__, __LINE__);
5245         }
5246         /*------DEBUG LOG END------*/
5247
5248         return status;
5249 }
5250
5251 //! call from realserver disconnect. use upstream thread and downstream thread.
5252 //! @param[in]    upstream and downstream thread id( check! one thread one event )
5253 //! @param[in]    disconnect realserver endpoint
5254 //! @return        session use EVENT mode.
5255 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_close(
5256         const boost::thread::id thread_id, const boost::asio::ip::udp::endpoint &rs_endpoint)
5257 {
5258         /*-------- DEBUG LOG --------*/
5259         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5260                 boost::format formatter("in/out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5261                                         "handle_realserver_close(const boost::thread::id thread_id, "
5262                                         "boost::asio::ip::udp::endpoint& rs_endpoint) : "
5263                                         "return_value = %d. thread id : %d.");
5264                 formatter % STOP % boost::this_thread::get_id();
5265                 putLogDebug(600159, formatter.str(), __FILE__, __LINE__);
5266         }
5267         /*------DEBUG LOG END------*/
5268
5269         return STOP;
5270 }
5271
5272
5273 bool  protocol_module_ip::get_data_from_recvbuffer(
5274         thread_data_ptr data_ptr, const boost::array<char, MAX_BUFFER_SIZE>& recvbuffer, const size_t recvlen)
5275 {
5276         /*-------- DEBUG LOG --------*/
5277         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5278                 boost::format formatter("in_function : bool protocol_module_ip::get_data_from_recvbuffer("
5279                                         "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5280                                         "const size_t& recvlen) : thread_id = %d.");
5281                 formatter % boost::this_thread::get_id();
5282                 putLogDebug(600160, formatter.str(), __FILE__, __LINE__);
5283         }
5284         /*------DEBUG LOG END------*/
5285
5286         char *tmpbuffer = NULL;
5287
5288         //pointer validate check
5289         if (unlikely(data_ptr == NULL || data_ptr->data_buffer == NULL)) {
5290                 boost::format formatter("Invalid pointer. thread id : %d.");
5291                 formatter % boost::this_thread::get_id();
5292                 putLogError(600099, formatter.str(), __FILE__, __LINE__);
5293
5294                 /*-------- DEBUG LOG --------*/
5295                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5296                         boost::format formatter("out_function : bool protocol_module_ip::get_data_from_recvbuffer("
5297                                                 "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5298                                                 "const size_t& recvlen) : return_value = false. thread id : %d.");
5299                         formatter % boost::this_thread::get_id();
5300                         putLogDebug(600161, formatter.str(), __FILE__, __LINE__);
5301                 }
5302                 /*------DEBUG LOG END------*/
5303
5304                 return false;
5305         }
5306
5307
5308         //the new data can append to buffer directly
5309         if (data_ptr->data_buffer_size - data_ptr->data_length - data_ptr->data_offset >= recvlen) {
5310
5311                 /*-------- DEBUG LOG --------*/
5312                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5313                         std::string datadump;
5314                         dump_memory(recvbuffer.data(), recvlen, datadump);
5315                         boost::format formatter(
5316                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5317                                 "get_data_from_recvbuffer() : before memcpy (data dump) : "
5318                                 "data begin = 0, data_size = %d, data = %s");
5319                         formatter % recvlen % datadump;
5320                         putLogDebug(600162, formatter.str(), __FILE__, __LINE__);
5321                 }
5322                 /*------DEBUG LOG END------*/
5323
5324                 memcpy(data_ptr->data_buffer + data_ptr->data_offset + data_ptr->data_length, recvbuffer.data(), recvlen);
5325
5326                 /*-------- DEBUG LOG --------*/
5327                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5328                         std::string datadump;
5329                         dump_memory(data_ptr->data_buffer + data_ptr->data_offset + data_ptr->data_length, recvlen, datadump);
5330                         boost::format formatter(
5331                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5332                                 "get_data_from_recvbuffer() : after memcpy (data dump) : "
5333                                 "data begin = 0, data_size = %d, data = %s");
5334                         formatter % recvlen % datadump;
5335                         putLogDebug(600163, formatter.str(), __FILE__, __LINE__);
5336                 }
5337                 /*------DEBUG LOG END------*/
5338
5339                 data_ptr->data_length += recvlen;
5340
5341                 /*-------- DEBUG LOG --------*/
5342                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5343                         boost::format formatter("out_function : bool protocol_module_ip::get_data_from_recvbuffer("
5344                                                 "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5345                                                 "const size_t& recvlen) : return_value = true. thread id : %d.");
5346                         formatter % boost::this_thread::get_id();
5347                         putLogDebug(600164, formatter.str(), __FILE__, __LINE__);
5348                 }
5349                 /*------DEBUG LOG END------*/
5350                 return true;
5351         } else {
5352                 //the new data can append to buffer through moving original data
5353                 if (data_ptr->data_buffer_size - data_ptr->data_length >= recvlen) {
5354                         memmove(data_ptr->data_buffer, data_ptr->data_buffer + data_ptr->data_offset, data_ptr->data_length);
5355                         /*-------- DEBUG LOG --------*/
5356                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5357                                 std::string datadump;
5358                                 dump_memory(recvbuffer.data(), recvlen, datadump);
5359                                 boost::format formatter(
5360                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5361                                         "get_data_from_recvbuffer() : before memcpy (data dump) : "
5362                                         "data begin = 0, data_size = %d, data = %s");
5363                                 formatter % recvlen % datadump;
5364                                 putLogDebug(600165, formatter.str(), __FILE__, __LINE__);
5365                         }
5366                         /*------DEBUG LOG END------*/
5367
5368                         memcpy(data_ptr->data_buffer + data_ptr->data_length, recvbuffer.data(), recvlen);
5369
5370                         /*-------- DEBUG LOG --------*/
5371                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5372                                 std::string datadump;
5373                                 dump_memory(data_ptr->data_buffer + data_ptr->data_length, recvlen, datadump);
5374                                 boost::format formatter(
5375                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5376                                         "get_data_from_recvbuffer() : after memcpy (data dump) : "
5377                                         "data begin = 0, data_size = %d, data = %s");
5378                                 formatter % recvlen % datadump;
5379                                 putLogDebug(600166, formatter.str(), __FILE__, __LINE__);
5380                         }
5381                         /*------DEBUG LOG END------*/
5382
5383                         data_ptr->data_offset = 0;
5384                         data_ptr->data_length += recvlen;
5385
5386                         /*-------- DEBUG LOG --------*/
5387                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5388                                 boost::format formatter("out_function : bool protocol_module_ip::get_data_from_recvbuffer("
5389                                                         "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5390                                                         "const size_t& recvlen) : return_value = true. thread id : %d.");
5391                                 formatter % boost::this_thread::get_id();
5392                                 putLogDebug(600167, formatter.str(), __FILE__, __LINE__);
5393                         }
5394                         /*------DEBUG LOG END------*/
5395
5396                         return true;
5397                 } else {
5398                         //not allowed to realloc new buffer who's size is larger than the max size
5399                         if (data_ptr->data_buffer_size >= MAX_IP_MODULE_BUFFER_SIZE
5400                             || data_ptr->data_buffer_size + recvlen >= MAX_IP_MODULE_BUFFER_SIZE) {
5401                                 boost::format formatter("Buffer size is bigger than Max size. thread id : %d.");
5402                                 formatter % boost::this_thread::get_id();
5403                                 putLogError(600100, formatter.str(), __FILE__, __LINE__);
5404
5405                                 /*-------- DEBUG LOG --------*/
5406                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5407                                         boost::format formatter("out_function : bool protocol_module_ip::get_data_from_recvbuffer("
5408                                                                 "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5409                                                                 "const size_t& recvlen) : return_value = false. thread id : %d.");
5410                                         formatter % boost::this_thread::get_id();
5411                                         putLogDebug(600168, formatter.str(), __FILE__, __LINE__);
5412                                 }
5413                                 /*------DEBUG LOG END------*/
5414
5415                                 return false;
5416                         } else {
5417                                 try {
5418                                         /*-------- DEBUG LOG --------*/
5419                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5420                                                 boost::format formatter("new : address = &(%d), size = %lu.");
5421                                                 formatter % static_cast<void *>(tmpbuffer) % MAX_IP_MODULE_BUFFER_SIZE;
5422                                                 putLogDebug(600169, formatter.str(), __FILE__, __LINE__);
5423                                         }
5424                                         /*------DEBUG LOG END------*/
5425
5426                                         //alloc a new buffer who's size is max
5427                                         tmpbuffer = new char[MAX_IP_MODULE_BUFFER_SIZE];
5428                                 } catch (const std::bad_alloc &) { //memory alloc fail
5429                                         std::cerr << "protocol_module_ip::get_data_from_recvbuffer() : exception : Could not allocate memory." << std::endl;
5430                                         boost::format formatter("Could not allocate memory. thread id : %d.");
5431                                         formatter % boost::this_thread::get_id();
5432                                         putLogError(600101, formatter.str(), __FILE__, __LINE__);
5433
5434                                         /*-------- DEBUG LOG --------*/
5435                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5436                                                 boost::format formatter("out_function : bool protocol_module_ip::get_data_from_recvbuffer("
5437                                                                         "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5438                                                                         "const size_t& recvlen) : return_value = false. thread id : %d.");
5439                                                 formatter % boost::this_thread::get_id();
5440                                                 putLogDebug(600170, formatter.str(), __FILE__, __LINE__);
5441                                         }
5442                                         /*------DEBUG LOG END------*/
5443
5444                                         return false;
5445                                 }
5446
5447                                 memset(tmpbuffer, 0, MAX_IP_MODULE_BUFFER_SIZE);
5448
5449                                 /*-------- DEBUG LOG --------*/
5450                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5451                                         std::string datadump;
5452                                         dump_memory(data_ptr->data_buffer + data_ptr->data_offset, data_ptr->data_length, datadump);
5453                                         boost::format formatter(
5454                                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5455                                                 "get_data_from_recvbuffer() : before memcpy (data dump) : "
5456                                                 "data begin = 0, data_size = %d, data = %s");
5457                                         formatter % data_ptr->data_length % datadump;
5458                                         putLogDebug(600171, formatter.str(), __FILE__, __LINE__);
5459                                 }
5460                                 /*------DEBUG LOG END------*/
5461
5462                                 //copy old data to new buffer
5463                                 memcpy(tmpbuffer, data_ptr->data_buffer + data_ptr->data_offset, data_ptr->data_length);
5464
5465                                 /*-------- DEBUG LOG --------*/
5466                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5467                                         std::string datadump;
5468                                         dump_memory(tmpbuffer, data_ptr->data_length, datadump);
5469                                         boost::format formatter(
5470                                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5471                                                 "get_data_from_recvbuffer() : after memcpy (data dump) : "
5472                                                 "data begin = 0, data_size = %d, data = %s");
5473                                         formatter % data_ptr->data_length % datadump;
5474                                         putLogDebug(600172, formatter.str(), __FILE__, __LINE__);
5475                                 }
5476                                 /*------DEBUG LOG END------*/
5477
5478                                 /*-------- DEBUG LOG --------*/
5479                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5480                                         boost::format formatter("delete : address = &(%d).");
5481                                         formatter % static_cast<void *>(data_ptr->data_buffer);
5482                                         putLogDebug(600173, formatter.str(), __FILE__, __LINE__);
5483                                 }
5484                                 /*------DEBUG LOG END------*/
5485
5486                                 //release old memory
5487                                 delete [] data_ptr->data_buffer;
5488                                 data_ptr->data_buffer = tmpbuffer;
5489                                 data_ptr->data_offset = 0;
5490
5491                                 /*-------- DEBUG LOG --------*/
5492                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5493                                         std::string datadump;
5494                                         dump_memory(recvbuffer.data(), recvlen, datadump);
5495                                         boost::format formatter(
5496                                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5497                                                 "get_data_from_recvbuffer() : before memcpy (data dump) : "
5498                                                 "data begin = 0, data_size = %d, data = %s");
5499                                         formatter % recvlen % datadump;
5500                                         putLogDebug(600174, formatter.str(), __FILE__, __LINE__);
5501                                 }
5502                                 /*------DEBUG LOG END------*/
5503
5504                                 //append new data
5505                                 memcpy(data_ptr->data_buffer + data_ptr->data_length, recvbuffer.data(), recvlen);
5506
5507                                 /*-------- DEBUG LOG --------*/
5508                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5509                                         std::string datadump;
5510                                         dump_memory(data_ptr->data_buffer + data_ptr->data_length, recvlen, datadump);
5511                                         boost::format formatter(
5512                                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5513                                                 "get_data_from_recvbuffer() : after memcpy (data dump) : "
5514                                                 "data begin = 0, data_size = %d, data = %s");
5515                                         formatter % recvlen % datadump;
5516                                         putLogDebug(600175, formatter.str(), __FILE__, __LINE__);
5517                                 }
5518                                 /*------DEBUG LOG END------*/
5519
5520                                 data_ptr->data_length += recvlen;
5521                                 data_ptr->data_buffer_size = MAX_IP_MODULE_BUFFER_SIZE ;
5522
5523                                 /*-------- DEBUG LOG --------*/
5524                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5525                                         boost::format formatter("out_function : bool protocol_module_ip::get_data_from_recvbuffer("
5526                                                                 "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5527                                                                 "const size_t& recvlen) : return_value = true. thread id : %d.");
5528                                         formatter % boost::this_thread::get_id();
5529                                         putLogDebug(600176, formatter.str(), __FILE__, __LINE__);
5530                                 }
5531                                 /*------DEBUG LOG END------*/
5532
5533                                 return true;
5534
5535                         }
5536                 }
5537         }
5538 }
5539
5540 bool protocol_module_ip::put_data_into_sendbuffer(
5541         thread_data_ptr data_ptr, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen)
5542 {
5543         /*-------- DEBUG LOG --------*/
5544         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5545                 boost::format formatter("in_function : bool protocol_module_ip::put_data_to_sendbuffer("
5546                                         "thread_data_ptr data_ptr, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
5547                                         "size_t& datalen) : thread_id = %d.");
5548                 formatter % boost::this_thread::get_id();
5549                 putLogDebug(600177, formatter.str(), __FILE__, __LINE__);
5550         }
5551         /*------DEBUG LOG END------*/
5552
5553         size_t sendbuffer_rest_size = 0;
5554         size_t new_offset        = 0;
5555
5556         if (unlikely(data_ptr == NULL || data_ptr->data_buffer == NULL || data_ptr->buffer_sequence.empty())) {
5557                 boost::format formatter("Invalid pointer. thread id : %d.");
5558                 formatter % boost::this_thread::get_id();
5559                 putLogError(600102, formatter.str(), __FILE__, __LINE__);
5560
5561                 /*-------- DEBUG LOG --------*/
5562                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5563                         boost::format formatter("out_function : bool protocol_module_ip::put_data_to_sendbuffer("
5564                                                 "thread_data_ptr data_ptr, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
5565                                                 "size_t& datalen) : return_value = false. thread_id = %d.");
5566                         formatter % boost::this_thread::get_id();
5567                         putLogDebug(600178, formatter.str(), __FILE__, __LINE__);
5568                 }
5569                 /*------DEBUG LOG END------*/
5570
5571                 return false;
5572         }
5573
5574         sendbuffer_rest_size = sendbuffer.size();
5575         datalen = 0;
5576
5577         //buffer_sequence loop
5578         //copy data to send buffer until send buffer is full
5579         while (data_ptr->buffer_sequence.size() > 0) {
5580                 std::pair<char *, size_t> buffer_element = data_ptr->buffer_sequence.front();
5581                 //sendbuffer rest size id bigger than copy possible size
5582                 if (buffer_element.second <= sendbuffer_rest_size) {
5583                         /*-------- DEBUG LOG --------*/
5584                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5585                                 std::string datadump;
5586                                 dump_memory(buffer_element.first, buffer_element.second, datadump);
5587                                 boost::format formatter(
5588                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5589                                         "put_data_to_sendbuffer() : before memcpy (data dump) : "
5590                                         "data begin = 0, data_size = %d, data = %s");
5591                                 formatter % buffer_element.second % datadump;
5592                                 putLogDebug(600179, formatter.str(), __FILE__, __LINE__);
5593                         }
5594                         /*------DEBUG LOG END------*/
5595
5596                         //copy data to send buffer
5597                         memcpy(sendbuffer.c_array() + datalen, buffer_element.first, buffer_element.second);
5598
5599                         /*-------- DEBUG LOG --------*/
5600                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5601                                 std::string datadump;
5602                                 dump_memory(sendbuffer.c_array() + datalen, buffer_element.second, datadump);
5603                                 boost::format formatter(
5604                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5605                                         "put_data_to_sendbuffer() : after memcpy (data dump) : "
5606                                         "data begin = 0, data_size = %d, data = %s");
5607                                 formatter % buffer_element.second % datadump;
5608                                 putLogDebug(600180, formatter.str(), __FILE__, __LINE__);
5609                         }
5610                         /*------DEBUG LOG END------*/
5611
5612                         datalen += buffer_element.second;
5613                         sendbuffer_rest_size -= buffer_element.second;
5614
5615                         //it is the last item of the sequence
5616                         if (data_ptr->buffer_sequence.size() == 1) {
5617                                 //set data position
5618                                 new_offset = buffer_element.first + buffer_element.second - data_ptr->data_buffer;
5619                                 data_ptr->current_message_rest_size -= (new_offset - data_ptr->data_offset);
5620                                 data_ptr->data_length -= (new_offset - data_ptr->data_offset);
5621                                 data_ptr->data_offset = new_offset;
5622                         }
5623
5624
5625                         //delete the item
5626                         data_ptr->buffer_sequence.pop_front();
5627                 }
5628                 //sendbuffer rest size is too small
5629                 else {
5630                         /*-------- DEBUG LOG --------*/
5631                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5632                                 std::string datadump;
5633                                 dump_memory(buffer_element.first, sendbuffer_rest_size, datadump);
5634                                 boost::format formatter(
5635                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5636                                         "put_data_to_sendbuffer() : before memcpy (data dump) : "
5637                                         "data begin = 0, data_size = %d, data = %s");
5638                                 formatter % sendbuffer_rest_size % datadump;
5639                                 putLogDebug(600181, formatter.str(), __FILE__, __LINE__);
5640                         }
5641                         /*------DEBUG LOG END------*/
5642
5643                         //copy data to send buffer
5644                         memcpy(sendbuffer.c_array() + datalen, buffer_element.first, sendbuffer_rest_size);
5645
5646                         /*-------- DEBUG LOG --------*/
5647                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5648                                 std::string datadump;
5649                                 dump_memory(sendbuffer.c_array() + datalen, sendbuffer_rest_size, datadump);
5650                                 boost::format formatter(
5651                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5652                                         "put_data_to_sendbuffer() : after memcpy (data dump) : "
5653                                         "data begin = 0, data_size = %d, data = %s");
5654                                 formatter % sendbuffer_rest_size % datadump;
5655                                 putLogDebug(600182, formatter.str(), __FILE__, __LINE__);
5656                         }
5657                         /*------DEBUG LOG END------*/
5658
5659                         datalen += sendbuffer_rest_size;
5660
5661                         //set item position
5662                         buffer_element.first += sendbuffer_rest_size;
5663                         buffer_element.second -= sendbuffer_rest_size;
5664                         sendbuffer_rest_size = 0;
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 }