OSDN Git Service

Fix header.(boost, STL, gcc4.3)
[ultramonkey-l7/ultramonkey-l7-v3.git] / l7vsd / module / protocol / protocol_module_sessionless.h
1 /*
2  * @file  protocol_module_sessionless.h
3  * @brief protocol module sessionless header file.
4  *
5  * L7VSD: Linux Virtual Server for Layer7 Load Balancing
6  * Copyright (C) 2009  NTT COMWARE Corporation.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  *
23  **********************************************************************/
24
25 #include <boost/thread/mutex.hpp>
26 #include <boost/lexical_cast.hpp>
27 #include "http_protocol_module_base.h"
28
29 #ifndef PROTOCOL_MODULE_SESSIONLESS_H
30 #define PROTOCOL_MODULE_SESSIONLESS_H
31
32 #define MAX_OPTION_SIZE 128
33 #define MAX_SESSIONLESS_MODULE_BUFFER_SIZE (8190 + MAX_BUFFER_SIZE)
34
35 namespace l7vs
36 {
37
38 class protocol_module_sessionless : public http_protocol_module_base
39 {
40 public:
41         enum SEND_STATUS_TAG {
42                 SEND_OK = 0,
43                 SEND_NG,
44                 SEND_END,
45                 SEND_CONTINUE
46         };
47         struct edit_data {
48                 std::string data;
49                 size_t data_size;
50                 size_t insert_posission;
51                 size_t replace_size;
52         } ;
53
54         struct send_status {
55                 SEND_STATUS_TAG status;
56                 size_t send_end_size;
57                 size_t send_rest_size;
58                 size_t send_possible_size;
59                 size_t send_offset;
60                 size_t unsend_size;
61                 int edit_division;
62                 boost::asio::ip::tcp::endpoint send_endpoint;
63                 std::list<edit_data> edit_data_list;
64         };
65
66         struct receive_data {
67                 char *receive_buffer;
68                 char *receive_buffer1;
69                 char *receive_buffer2;
70                 size_t receive_buffer_max_size;
71                 size_t receive_buffer_rest_size;
72                 std::list<send_status>  send_status_list;
73                 receive_data() {
74                         receive_buffer1 = NULL;
75                         receive_buffer2 = NULL;
76                         receive_buffer = NULL;
77                         receive_buffer_max_size = 0;
78                         receive_buffer_rest_size = 0;
79                 }
80                 ~receive_data() {
81                         if (receive_buffer1 != NULL) {
82                                 delete [] receive_buffer1;
83                                 receive_buffer1 = NULL;
84                         }
85
86                         if (receive_buffer2 != NULL) {
87                                 delete [] receive_buffer2;
88                                 receive_buffer2 = NULL;
89                         }
90
91                         receive_buffer = NULL;
92                         receive_buffer_max_size = 0;
93                         receive_buffer_rest_size = 0;
94                 }
95         };
96
97
98         struct session_thread_data_sessionless {
99                 boost::thread::id thread_id;
100                 int thread_division;
101                 boost::thread::id pair_thread_id;
102                 std::map<boost::asio::ip::tcp::endpoint, receive_data> receive_data_map;
103                 int end_flag;
104                 int accept_end_flag;
105                 int sorry_flag;
106                 int sorryserver_switch_flag;
107                 int realserver_switch_flag;
108                 boost::asio::ip::tcp::endpoint target_endpoint;
109                 boost::asio::ip::tcp::endpoint client_endpoint_tcp;
110                 EVENT_TAG last_status;
111         };
112
113         typedef std::list<send_status>::iterator send_status_it;
114         typedef boost::shared_ptr<session_thread_data_sessionless> thread_data_ptr;
115         typedef std::map<boost::thread::id, thread_data_ptr>::iterator session_thread_data_map_it;
116         typedef std::map<boost::asio::ip::tcp::endpoint, receive_data>::iterator receive_data_map_it;
117 protected:
118         int forwarded_for;
119         boost:: array<char, MAX_OPTION_SIZE> sorry_uri ;
120         std::map<boost::thread::id, thread_data_ptr> session_thread_data_map;
121         boost::mutex    session_thread_data_map_mutex;
122
123 public:
124         static const std::string MODULE_NAME;
125
126         static const int THREAD_DIVISION_UP_STREAM;
127         static const int THREAD_DIVISION_DOWN_STREAM;
128
129         static const int END_FLAG_OFF;
130         static const int END_FLAG_ON;
131
132         static const int ACCEPT_END_FLAG_OFF;
133         static const int ACCEPT_END_FLAG_ON;
134
135         static const int SORRY_FLAG_ON;
136         static const int SORRY_FLAG_OFF;
137
138         static const int SORRYSERVER_SWITCH_FLAG_OFF;
139         static const int SORRYSERVER_SWITCH_FLAG_ON;
140
141         static const int REALSERVER_SWITCH_FLAG_OFF;
142         static const int REALSERVER_SWITCH_FLAG_ON;
143
144         static const int EDIT_DIVISION_NO_EDIT;
145         static const int EDIT_DIVISION_EDIT;
146
147         static const int FORWARDED_FOR_OFF;
148         static const int FORWARDED_FOR_ON;
149
150 public:
151         protocol_module_sessionless();
152         ~protocol_module_sessionless();
153
154         bool is_tcp();
155         bool is_udp();
156         void replication_interrupt();
157         void initialize(rs_list_itr_func_type    inlist_begin,
158                         rs_list_itr_func_type    inlist_end,
159                         rs_list_itr_next_func_type    inlist_next,
160                         boost::function< void(void) >    inlist_lock,
161                         boost::function< void(void) >    inlist_unlock);
162         void finalize();
163         bool is_use_sorry();
164         check_message_result check_parameter(const std::vector<std::string>& args);
165         check_message_result set_parameter(const std::vector<std::string>& args);
166         check_message_result add_parameter(const std::vector<std::string>& args);
167         void get_option_info(std::string &option);
168         void handle_rslist_update();
169         void register_schedule(tcp_schedule_func_type inschedule);
170         void register_schedule(udp_schedule_func_type inschedule);
171         EVENT_TAG handle_session_initialize(const boost::thread::id up_thread_id, const boost::thread::id down_thread_id, const boost::asio::ip::tcp::endpoint &client_endpoint_tcp, const boost::asio::ip::udp::endpoint &client_endpoint_udp);
172         EVENT_TAG handle_session_finalize(const boost::thread::id up_thread_id, const boost::thread::id down_thread_id);
173         EVENT_TAG handle_accept(const boost::thread::id thread_id);
174         EVENT_TAG handle_client_recv(const boost::thread::id thread_id, const boost::array<char, MAX_BUFFER_SIZE>& recvbuffer, const size_t recvlen);
175         EVENT_TAG handle_realserver_select(const boost::thread::id thread_id, boost::asio::ip::tcp::endpoint &rs_endpoint);
176         EVENT_TAG handle_realserver_select(const boost::thread::id thread_id, boost::asio::ip::udp::endpoint &rs_endpoint, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen);
177         EVENT_TAG handle_realserver_connect(const boost::thread::id thread_id, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen);
178         EVENT_TAG handle_realserver_connection_fail(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &rs_endpoint);
179         EVENT_TAG handle_realserver_send(const boost::thread::id thread_id);
180         EVENT_TAG handle_sorryserver_select(const boost::thread::id thread_id, boost::asio::ip::tcp::endpoint &sorry_endpoint);
181         EVENT_TAG handle_sorryserver_connect(const boost::thread::id thread_id, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen);
182         EVENT_TAG handle_sorryserver_connection_fail(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &sorry_endpoint);
183         EVENT_TAG handle_sorryserver_send(const boost::thread::id thread_id);
184         EVENT_TAG handle_realserver_recv(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &rs_endpoint, const boost::array<char, MAX_BUFFER_SIZE>& recvbuffer, const size_t recvlen);
185         EVENT_TAG handle_realserver_recv(const boost::thread::id thread_id, const boost::asio::ip::udp::endpoint &rs_endpoint, const boost::array<char, MAX_BUFFER_SIZE>& recvbuffer, const size_t recvlen);
186         EVENT_TAG handle_sorryserver_recv(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &sorry_endpoint, const boost::array<char, MAX_BUFFER_SIZE>& recvbuffer, const size_t recvlen);
187         EVENT_TAG handle_response_send_inform(const boost::thread::id thread_id);
188         EVENT_TAG handle_client_connection_check(const boost::thread::id thread_id, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen);
189         EVENT_TAG handle_client_select(const boost::thread::id thread_id, boost::asio::ip::udp::endpoint &cl_endpoint, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen);
190         EVENT_TAG handle_client_send(const boost::thread::id thread_id);
191         EVENT_TAG handle_client_disconnect(const boost::thread::id thread_id);
192         EVENT_TAG handle_sorry_enable(const boost::thread::id thread_id);
193         EVENT_TAG handle_sorry_disable(const boost::thread::id thread_id);
194         EVENT_TAG handle_realserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &rs_endpoint);
195         EVENT_TAG handle_sorryserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &sorry_endpoint);
196         EVENT_TAG handle_realserver_close(const boost::thread::id thread_id, const boost::asio::ip::udp::endpoint &rs_endpoint);
197 };
198
199 inline bool operator < (const protocol_module_sessionless::edit_data &lref, const protocol_module_sessionless::edit_data &rref)
200 {
201         return lref.insert_posission < rref.insert_posission;
202 }
203
204 class data_send_possible
205 {
206 public:
207         inline bool operator()(const protocol_module_sessionless::send_status &send_status) {
208                 return send_status.status == protocol_module_sessionless::SEND_OK
209                        &&  send_status.send_possible_size > 0;
210         }
211 };
212
213 class data_send_disable
214 {
215 public:
216         inline bool operator()(const protocol_module_sessionless::send_status &send_status) {
217                 return send_status.status == protocol_module_sessionless::SEND_NG
218                        || send_status.send_rest_size > 0 ;
219         }
220 };
221
222 class data_send_continue
223 {
224 public:
225         inline bool operator()(const protocol_module_sessionless::send_status &send_status) {
226                 return send_status.status == protocol_module_sessionless::SEND_CONTINUE;
227         }
228 };
229
230 class data_send_ng
231 {
232 public:
233         inline bool operator()(const protocol_module_sessionless::send_status &send_status) {
234                 return send_status.status == protocol_module_sessionless::SEND_NG;
235         }
236 };
237
238 class data_send_ok
239 {
240 public:
241         inline bool operator()(const protocol_module_sessionless::send_status &send_status) {
242                 return send_status.status == protocol_module_sessionless::SEND_OK;
243         }
244 };
245
246 class data_send_repeated
247 {
248 public:
249         inline bool operator()(const protocol_module_sessionless::send_status &send_status_first,
250                                const protocol_module_sessionless::send_status &send_status_second) {
251                 return send_status_first.status == protocol_module_sessionless::SEND_NG
252                        || send_status_first.status == protocol_module_sessionless::SEND_CONTINUE;
253         }
254 };
255
256 class data_send_list_incorrect
257 {
258 public:
259         inline bool operator()(const protocol_module_sessionless::send_status &send_status_first,
260                                const protocol_module_sessionless::send_status &send_status_second) {
261                 return (send_status_first.status == protocol_module_sessionless::SEND_OK
262                         && send_status_first.send_rest_size > 0)
263                        || (send_status_first.status == protocol_module_sessionless::SEND_CONTINUE)
264                        || (send_status_first.status == protocol_module_sessionless::SEND_NG);
265         }
266 };
267
268 class rs_list_scoped_lock
269 {
270 protected:
271         boost::function< void(void) >    rs_list_unlock;
272 public:
273         rs_list_scoped_lock(boost::function< void(void) >    inlist_lock,
274                             boost::function< void(void) >    inlist_unlock) {
275                 inlist_lock();
276                 rs_list_unlock = inlist_unlock;
277         }
278         ~rs_list_scoped_lock() {
279                 rs_list_unlock();
280         }
281 };
282 }
283
284 #endif  //PROTOCOL_MODULE_SESSIONLESS_H
285