2 * @file protocol_module_sessionless.h
3 * @brief protocol module sessionless header file.
5 * L7VSD: Linux Virtual Server for Layer7 Load Balancing
6 * Copyright (C) 2009 NTT COMWARE Corporation.
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.
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.
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
23 **********************************************************************/
25 #include <boost/thread/mutex.hpp>
26 #include "http_protocol_module_base.h"
28 #ifndef PROTOCOL_MODULE_SESSIONLESS_H
29 #define PROTOCOL_MODULE_SESSIONLESS_H
31 #define MAX_OPTION_SIZE 128
32 #define MAX_SESSIONLESS_MODULE_BUFFER_SIZE (8190 + MAX_BUFFER_SIZE)
37 class protocol_module_sessionless : public http_protocol_module_base
40 enum SEND_STATUS_TAG {
49 size_t insert_posission;
54 SEND_STATUS_TAG status;
56 size_t send_rest_size;
57 size_t send_possible_size;
61 boost::asio::ip::tcp::endpoint send_endpoint;
62 std::list<edit_data> edit_data_list;
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;
73 receive_buffer1 = NULL;
74 receive_buffer2 = NULL;
75 receive_buffer = NULL;
76 receive_buffer_max_size = 0;
77 receive_buffer_rest_size = 0;
80 if (receive_buffer1 != NULL) {
81 delete [] receive_buffer1;
82 receive_buffer1 = NULL;
85 if (receive_buffer2 != NULL) {
86 delete [] receive_buffer2;
87 receive_buffer2 = NULL;
90 receive_buffer = NULL;
91 receive_buffer_max_size = 0;
92 receive_buffer_rest_size = 0;
97 struct session_thread_data_sessionless {
98 boost::thread::id thread_id;
100 boost::thread::id pair_thread_id;
101 std::map<boost::asio::ip::tcp::endpoint, receive_data> receive_data_map;
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;
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;
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;
123 static const std::string MODULE_NAME;
125 static const int THREAD_DIVISION_UP_STREAM;
126 static const int THREAD_DIVISION_DOWN_STREAM;
128 static const int END_FLAG_OFF;
129 static const int END_FLAG_ON;
131 static const int ACCEPT_END_FLAG_OFF;
132 static const int ACCEPT_END_FLAG_ON;
134 static const int SORRY_FLAG_ON;
135 static const int SORRY_FLAG_OFF;
137 static const int SORRYSERVER_SWITCH_FLAG_OFF;
138 static const int SORRYSERVER_SWITCH_FLAG_ON;
140 static const int REALSERVER_SWITCH_FLAG_OFF;
141 static const int REALSERVER_SWITCH_FLAG_ON;
143 static const int EDIT_DIVISION_NO_EDIT;
144 static const int EDIT_DIVISION_EDIT;
146 static const int FORWARDED_FOR_OFF;
147 static const int FORWARDED_FOR_ON;
150 protocol_module_sessionless();
151 ~protocol_module_sessionless();
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);
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);
198 inline bool operator < (const protocol_module_sessionless::edit_data &lref, const protocol_module_sessionless::edit_data &rref)
200 return lref.insert_posission < rref.insert_posission;
203 class data_send_possible
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;
212 class data_send_disable
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 ;
221 class data_send_continue
224 inline bool operator()(const protocol_module_sessionless::send_status &send_status) {
225 return send_status.status == protocol_module_sessionless::SEND_CONTINUE;
232 inline bool operator()(const protocol_module_sessionless::send_status &send_status) {
233 return send_status.status == protocol_module_sessionless::SEND_NG;
240 inline bool operator()(const protocol_module_sessionless::send_status &send_status) {
241 return send_status.status == protocol_module_sessionless::SEND_OK;
245 class data_send_repeated
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;
255 class data_send_list_incorrect
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);
267 class rs_list_scoped_lock
270 boost::function< void(void) > rs_list_unlock;
272 rs_list_scoped_lock(boost::function< void(void) > inlist_lock,
273 boost::function< void(void) > inlist_unlock) {
275 rs_list_unlock = inlist_unlock;
277 ~rs_list_scoped_lock() {
283 #endif //PROTOCOL_MODULE_SESSIONLESS_H