OSDN Git Service

sessionless: typo fix (recive -> receive), do http parse only if forwarded_for =...
[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     {
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         {
75             receive_buffer1 = NULL;
76             receive_buffer2 = NULL;
77             receive_buffer = NULL;
78             receive_buffer_max_size = 0;
79             receive_buffer_rest_size = 0;
80         }
81         ~receive_data()
82         {
83             if (receive_buffer1 != NULL)
84             {
85                 delete [] receive_buffer1;
86                 receive_buffer1 = NULL;
87             }
88
89             if (receive_buffer2 != NULL)
90             {
91                 delete [] receive_buffer2;
92                 receive_buffer2 = NULL;
93             }
94
95             receive_buffer = NULL;
96             receive_buffer_max_size = 0;
97             receive_buffer_rest_size = 0;
98         }
99     };
100
101
102     struct session_thread_data_sessionless {
103         boost::thread::id thread_id;
104         int thread_division;
105         boost::thread::id pair_thread_id;
106         std::map<boost::asio::ip::tcp::endpoint, receive_data> receive_data_map;
107         int end_flag;
108         int accept_end_flag;
109         int sorry_flag;
110         int sorryserver_switch_flag;
111         int realserver_switch_flag;
112         boost::asio::ip::tcp::endpoint target_endpoint;
113         boost::asio::ip::tcp::endpoint client_endpoint_tcp;
114         EVENT_TAG last_status;
115     };
116
117    typedef std::list<send_status>::iterator send_status_it;
118    typedef boost::shared_ptr<session_thread_data_sessionless> thread_data_ptr;
119    typedef std::map<boost::thread::id, thread_data_ptr>::iterator session_thread_data_map_it;
120    typedef std::map<boost::asio::ip::tcp::endpoint, receive_data>::iterator receive_data_map_it;
121 protected:
122     int forwarded_for;
123     boost:: array<char,MAX_OPTION_SIZE> sorry_uri ;
124     std::map<boost::thread::id, thread_data_ptr> session_thread_data_map;
125     boost::mutex    session_thread_data_map_mutex;
126
127 public:
128     static const std::string MODULE_NAME;
129
130     static const int THREAD_DIVISION_UP_STREAM;
131     static const int THREAD_DIVISION_DOWN_STREAM;
132
133     static const int END_FLAG_OFF;
134     static const int END_FLAG_ON;
135
136     static const int ACCEPT_END_FLAG_OFF;
137     static const int ACCEPT_END_FLAG_ON;
138
139     static const int SORRY_FLAG_ON;
140     static const int SORRY_FLAG_OFF;
141
142     static const int SORRYSERVER_SWITCH_FLAG_OFF;
143     static const int SORRYSERVER_SWITCH_FLAG_ON;
144
145     static const int REALSERVER_SWITCH_FLAG_OFF;
146     static const int REALSERVER_SWITCH_FLAG_ON;
147
148     static const int EDIT_DIVISION_NO_EDIT;
149     static const int EDIT_DIVISION_EDIT;
150
151     static const int FORWARDED_FOR_OFF;
152     static const int FORWARDED_FOR_ON;
153
154 public:
155     protocol_module_sessionless();
156     ~protocol_module_sessionless();
157
158     bool is_tcp();
159     bool is_udp();
160     void replication_interrupt();
161     void initialize(rs_list_itr_func_type    inlist_begin,
162             rs_list_itr_func_type    inlist_end,
163             rs_list_itr_next_func_type    inlist_next,
164             boost::function< void( void ) >    inlist_lock,
165             boost::function< void( void ) >    inlist_unlock);
166     void finalize();
167     bool is_use_sorry();
168     check_message_result check_parameter(const std::vector<std::string>& args);
169     check_message_result set_parameter(const std::vector<std::string>& args);
170     check_message_result add_parameter(const std::vector<std::string>& args);
171     void get_option_info(std::string& option);
172     void handle_rslist_update();
173     void register_schedule(tcp_schedule_func_type inschedule);
174     void register_schedule(udp_schedule_func_type inschedule);
175     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);
176     EVENT_TAG handle_session_finalize(const boost::thread::id up_thread_id, const boost::thread::id down_thread_id);
177     EVENT_TAG handle_accept(const boost::thread::id thread_id);
178     EVENT_TAG handle_client_recv(const boost::thread::id thread_id, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, const size_t recvlen);
179     EVENT_TAG handle_realserver_select(const boost::thread::id thread_id, boost::asio::ip::tcp::endpoint& rs_endpoint);
180     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);
181     EVENT_TAG handle_realserver_connect(const boost::thread::id thread_id, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, size_t& datalen);
182     EVENT_TAG handle_realserver_connection_fail(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint& rs_endpoint);
183     EVENT_TAG handle_realserver_send(const boost::thread::id thread_id);
184     EVENT_TAG handle_sorryserver_select(const boost::thread::id thread_id, boost::asio::ip::tcp::endpoint& sorry_endpoint);
185     EVENT_TAG handle_sorryserver_connect(const boost::thread::id thread_id, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, size_t& datalen);
186     EVENT_TAG handle_sorryserver_connection_fail(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint& sorry_endpoint);
187     EVENT_TAG handle_sorryserver_send(const boost::thread::id thread_id);
188     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);
189     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);
190     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);
191     EVENT_TAG handle_response_send_inform(const boost::thread::id thread_id);
192     EVENT_TAG handle_client_connection_check(const boost::thread::id thread_id, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, size_t& datalen);
193     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);
194     EVENT_TAG handle_client_send(const boost::thread::id thread_id);
195     EVENT_TAG handle_client_disconnect(const boost::thread::id thread_id);
196     EVENT_TAG handle_sorry_enable(const boost::thread::id thread_id);
197     EVENT_TAG handle_sorry_disable(const boost::thread::id thread_id);
198     EVENT_TAG handle_realserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint& rs_endpoint);
199     EVENT_TAG handle_sorryserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint& sorry_endpoint);
200     EVENT_TAG handle_realserver_close(const boost::thread::id thread_id, const boost::asio::ip::udp::endpoint& rs_endpoint);
201 };
202
203 inline bool operator < (const protocol_module_sessionless::edit_data& lref, const protocol_module_sessionless::edit_data& rref)
204 {
205     return lref.insert_posission < rref.insert_posission;
206 }
207
208 class data_send_possible
209 {
210 public:
211     inline bool operator () (const protocol_module_sessionless::send_status& send_status)
212     {
213         return send_status.status == protocol_module_sessionless::SEND_OK
214                 &&  send_status.send_possible_size > 0;
215     }
216 };
217
218 class data_send_disable
219 {
220 public:
221     inline bool operator () (const protocol_module_sessionless::send_status& send_status)
222     {
223         return send_status.status == protocol_module_sessionless::SEND_NG
224         || send_status.send_rest_size > 0 ;
225     }
226 };
227
228 class data_send_continue
229 {
230 public:
231     inline bool operator () (const protocol_module_sessionless::send_status& send_status)
232     {
233         return send_status.status == protocol_module_sessionless::SEND_CONTINUE;
234     }
235 };
236
237 class data_send_ng
238 {
239 public:
240     inline bool operator ()(const protocol_module_sessionless::send_status& send_status)
241     {
242         return send_status.status == protocol_module_sessionless::SEND_NG;
243     }
244 };
245
246 class data_send_ok
247 {
248 public:
249     inline bool operator ()(const protocol_module_sessionless::send_status& send_status)
250     {
251         return send_status.status == protocol_module_sessionless::SEND_OK;
252     }
253 };
254
255 class data_send_repeated
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     {
261         return send_status_first.status == protocol_module_sessionless::SEND_NG
262         || send_status_first.status == protocol_module_sessionless::SEND_CONTINUE;
263     }
264 };
265
266 class data_send_list_incorrect
267 {
268 public:
269     inline bool operator ()(const protocol_module_sessionless::send_status& send_status_first,
270             const protocol_module_sessionless::send_status& send_status_second)
271     {
272         return (send_status_first.status == protocol_module_sessionless::SEND_OK
273         && send_status_first.send_rest_size > 0)
274         || (send_status_first.status == protocol_module_sessionless::SEND_CONTINUE)
275         || (send_status_first.status == protocol_module_sessionless::SEND_NG);
276     }
277 };
278
279 class rs_list_scoped_lock {
280     protected: 
281         boost::function< void( void ) >    rs_list_unlock;
282     public:
283         rs_list_scoped_lock(boost::function< void( void ) >    inlist_lock,
284                             boost::function< void( void ) >    inlist_unlock) 
285         {
286             inlist_lock();
287             rs_list_unlock = inlist_unlock; 
288         }
289         ~rs_list_scoped_lock() { rs_list_unlock(); }
290 };
291 }
292
293 #endif  //PROTOCOL_MODULE_SESSIONLESS_H
294