OSDN Git Service

formatted all files with 'astyle -A8 -HUpc -k3 -z2 -r ./*.cpp ./*.c ./*.h'
[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 "http_protocol_module_base.h"
27
28 #ifndef PROTOCOL_MODULE_SESSIONLESS_H
29 #define PROTOCOL_MODULE_SESSIONLESS_H
30
31 #define MAX_OPTION_SIZE 128
32 #define MAX_SESSIONLESS_MODULE_BUFFER_SIZE (8190 + MAX_BUFFER_SIZE)
33
34 namespace l7vs
35 {
36
37 class protocol_module_sessionless : public http_protocol_module_base
38 {
39 public:
40         enum SEND_STATUS_TAG {
41                 SEND_OK = 0,
42                 SEND_NG,
43                 SEND_END,
44                 SEND_CONTINUE
45         };
46         struct edit_data {
47                 std::string data;
48                 size_t data_size;
49                 size_t insert_posission;
50                 size_t replace_size;
51         } ;
52
53         struct send_status {
54                 SEND_STATUS_TAG status;
55                 size_t send_end_size;
56                 size_t send_rest_size;
57                 size_t send_possible_size;
58                 size_t send_offset;
59                 size_t unsend_size;
60                 int edit_division;
61                 boost::asio::ip::tcp::endpoint send_endpoint;
62                 std::list<edit_data> edit_data_list;
63         };
64
65         struct receive_data {
66                 char *receive_buffer;
67                 char *receive_buffer1;
68                 char *receive_buffer2;
69                 size_t receive_buffer_max_size;
70                 size_t receive_buffer_rest_size;
71                 std::list<send_status>  send_status_list;
72                 receive_data() {
73                         receive_buffer1 = NULL;
74                         receive_buffer2 = NULL;
75                         receive_buffer = NULL;
76                         receive_buffer_max_size = 0;
77                         receive_buffer_rest_size = 0;
78                 }
79                 ~receive_data() {
80                         if (receive_buffer1 != NULL) {
81                                 delete [] receive_buffer1;
82                                 receive_buffer1 = NULL;
83                         }
84
85                         if (receive_buffer2 != NULL) {
86                                 delete [] receive_buffer2;
87                                 receive_buffer2 = NULL;
88                         }
89
90                         receive_buffer = NULL;
91                         receive_buffer_max_size = 0;
92                         receive_buffer_rest_size = 0;
93                 }
94         };
95
96
97         struct session_thread_data_sessionless {
98                 boost::thread::id thread_id;
99                 int thread_division;
100                 boost::thread::id pair_thread_id;
101                 std::map<boost::asio::ip::tcp::endpoint, receive_data> receive_data_map;
102                 int end_flag;
103                 int accept_end_flag;
104                 int sorry_flag;
105                 int sorryserver_switch_flag;
106                 int realserver_switch_flag;
107                 boost::asio::ip::tcp::endpoint target_endpoint;
108                 boost::asio::ip::tcp::endpoint client_endpoint_tcp;
109                 EVENT_TAG last_status;
110         };
111
112         typedef std::list<send_status>::iterator send_status_it;
113         typedef boost::shared_ptr<session_thread_data_sessionless> thread_data_ptr;
114         typedef std::map<boost::thread::id, thread_data_ptr>::iterator session_thread_data_map_it;
115         typedef std::map<boost::asio::ip::tcp::endpoint, receive_data>::iterator receive_data_map_it;
116 protected:
117         int forwarded_for;
118         boost:: array<char, MAX_OPTION_SIZE> sorry_uri ;
119         std::map<boost::thread::id, thread_data_ptr> session_thread_data_map;
120         boost::mutex    session_thread_data_map_mutex;
121
122 public:
123         static const std::string MODULE_NAME;
124
125         static const int THREAD_DIVISION_UP_STREAM;
126         static const int THREAD_DIVISION_DOWN_STREAM;
127
128         static const int END_FLAG_OFF;
129         static const int END_FLAG_ON;
130
131         static const int ACCEPT_END_FLAG_OFF;
132         static const int ACCEPT_END_FLAG_ON;
133
134         static const int SORRY_FLAG_ON;
135         static const int SORRY_FLAG_OFF;
136
137         static const int SORRYSERVER_SWITCH_FLAG_OFF;
138         static const int SORRYSERVER_SWITCH_FLAG_ON;
139
140         static const int REALSERVER_SWITCH_FLAG_OFF;
141         static const int REALSERVER_SWITCH_FLAG_ON;
142
143         static const int EDIT_DIVISION_NO_EDIT;
144         static const int EDIT_DIVISION_EDIT;
145
146         static const int FORWARDED_FOR_OFF;
147         static const int FORWARDED_FOR_ON;
148
149 public:
150         protocol_module_sessionless();
151         ~protocol_module_sessionless();
152
153         bool is_tcp();
154         bool is_udp();
155         void replication_interrupt();
156         void initialize(rs_list_itr_func_type    inlist_begin,
157                         rs_list_itr_func_type    inlist_end,
158                         rs_list_itr_next_func_type    inlist_next,
159                         boost::function< void(void) >    inlist_lock,
160                         boost::function< void(void) >    inlist_unlock);
161         void finalize();
162         bool is_use_sorry();
163         check_message_result check_parameter(const std::vector<std::string>& args);
164         check_message_result set_parameter(const std::vector<std::string>& args);
165         check_message_result add_parameter(const std::vector<std::string>& args);
166         void get_option_info(std::string &option);
167         void handle_rslist_update();
168         void register_schedule(tcp_schedule_func_type inschedule);
169         void register_schedule(udp_schedule_func_type inschedule);
170         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);
171         EVENT_TAG handle_session_finalize(const boost::thread::id up_thread_id, const boost::thread::id down_thread_id);
172         EVENT_TAG handle_accept(const boost::thread::id thread_id);
173         EVENT_TAG handle_client_recv(const boost::thread::id thread_id, const boost::array<char, MAX_BUFFER_SIZE>& recvbuffer, const size_t recvlen);
174         EVENT_TAG handle_realserver_select(const boost::thread::id thread_id, boost::asio::ip::tcp::endpoint &rs_endpoint);
175         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);
176         EVENT_TAG handle_realserver_connect(const boost::thread::id thread_id, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen);
177         EVENT_TAG handle_realserver_connection_fail(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &rs_endpoint);
178         EVENT_TAG handle_realserver_send(const boost::thread::id thread_id);
179         EVENT_TAG handle_sorryserver_select(const boost::thread::id thread_id, boost::asio::ip::tcp::endpoint &sorry_endpoint);
180         EVENT_TAG handle_sorryserver_connect(const boost::thread::id thread_id, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen);
181         EVENT_TAG handle_sorryserver_connection_fail(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &sorry_endpoint);
182         EVENT_TAG handle_sorryserver_send(const boost::thread::id thread_id);
183         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);
184         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);
185         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);
186         EVENT_TAG handle_response_send_inform(const boost::thread::id thread_id);
187         EVENT_TAG handle_client_connection_check(const boost::thread::id thread_id, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen);
188         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);
189         EVENT_TAG handle_client_send(const boost::thread::id thread_id);
190         EVENT_TAG handle_client_disconnect(const boost::thread::id thread_id);
191         EVENT_TAG handle_sorry_enable(const boost::thread::id thread_id);
192         EVENT_TAG handle_sorry_disable(const boost::thread::id thread_id);
193         EVENT_TAG handle_realserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &rs_endpoint);
194         EVENT_TAG handle_sorryserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &sorry_endpoint);
195         EVENT_TAG handle_realserver_close(const boost::thread::id thread_id, const boost::asio::ip::udp::endpoint &rs_endpoint);
196 };
197
198 inline bool operator < (const protocol_module_sessionless::edit_data &lref, const protocol_module_sessionless::edit_data &rref)
199 {
200         return lref.insert_posission < rref.insert_posission;
201 }
202
203 class data_send_possible
204 {
205 public:
206         inline bool operator()(const protocol_module_sessionless::send_status &send_status) {
207                 return send_status.status == protocol_module_sessionless::SEND_OK
208                        &&  send_status.send_possible_size > 0;
209         }
210 };
211
212 class data_send_disable
213 {
214 public:
215         inline bool operator()(const protocol_module_sessionless::send_status &send_status) {
216                 return send_status.status == protocol_module_sessionless::SEND_NG
217                        || send_status.send_rest_size > 0 ;
218         }
219 };
220
221 class data_send_continue
222 {
223 public:
224         inline bool operator()(const protocol_module_sessionless::send_status &send_status) {
225                 return send_status.status == protocol_module_sessionless::SEND_CONTINUE;
226         }
227 };
228
229 class data_send_ng
230 {
231 public:
232         inline bool operator()(const protocol_module_sessionless::send_status &send_status) {
233                 return send_status.status == protocol_module_sessionless::SEND_NG;
234         }
235 };
236
237 class data_send_ok
238 {
239 public:
240         inline bool operator()(const protocol_module_sessionless::send_status &send_status) {
241                 return send_status.status == protocol_module_sessionless::SEND_OK;
242         }
243 };
244
245 class data_send_repeated
246 {
247 public:
248         inline bool operator()(const protocol_module_sessionless::send_status &send_status_first,
249                                const protocol_module_sessionless::send_status &send_status_second) {
250                 return send_status_first.status == protocol_module_sessionless::SEND_NG
251                        || send_status_first.status == protocol_module_sessionless::SEND_CONTINUE;
252         }
253 };
254
255 class data_send_list_incorrect
256 {
257 public:
258         inline bool operator()(const protocol_module_sessionless::send_status &send_status_first,
259                                const protocol_module_sessionless::send_status &send_status_second) {
260                 return (send_status_first.status == protocol_module_sessionless::SEND_OK
261                         && send_status_first.send_rest_size > 0)
262                        || (send_status_first.status == protocol_module_sessionless::SEND_CONTINUE)
263                        || (send_status_first.status == protocol_module_sessionless::SEND_NG);
264         }
265 };
266
267 class rs_list_scoped_lock
268 {
269 protected:
270         boost::function< void(void) >    rs_list_unlock;
271 public:
272         rs_list_scoped_lock(boost::function< void(void) >    inlist_lock,
273                             boost::function< void(void) >    inlist_unlock) {
274                 inlist_lock();
275                 rs_list_unlock = inlist_unlock;
276         }
277         ~rs_list_scoped_lock() {
278                 rs_list_unlock();
279         }
280 };
281 }
282
283 #endif  //PROTOCOL_MODULE_SESSIONLESS_H
284