OSDN Git Service

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