OSDN Git Service

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