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 <boost/lexical_cast.hpp>
27 #include "http_protocol_module_base.h"
29 #ifndef PROTOCOL_MODULE_SESSIONLESS_H
30 #define PROTOCOL_MODULE_SESSIONLESS_H
32 #define MAX_OPTION_SIZE 128
33 #define MAX_SESSIONLESS_MODULE_BUFFER_SIZE (8190 + MAX_BUFFER_SIZE)
38 class protocol_module_sessionless : public http_protocol_module_base
41 enum SEND_STATUS_TAG {
50 size_t insert_posission;
55 SEND_STATUS_TAG status;
57 size_t send_rest_size;
58 size_t send_possible_size;
62 boost::asio::ip::tcp::endpoint send_endpoint;
63 std::list<edit_data> edit_data_list;
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;
74 receive_buffer1 = NULL;
75 receive_buffer2 = NULL;
76 receive_buffer = NULL;
77 receive_buffer_max_size = 0;
78 receive_buffer_rest_size = 0;
81 if (receive_buffer1 != NULL) {
82 delete [] receive_buffer1;
83 receive_buffer1 = NULL;
86 if (receive_buffer2 != NULL) {
87 delete [] receive_buffer2;
88 receive_buffer2 = NULL;
91 receive_buffer = NULL;
92 receive_buffer_max_size = 0;
93 receive_buffer_rest_size = 0;
98 struct session_thread_data_sessionless {
99 boost::thread::id thread_id;
101 boost::thread::id pair_thread_id;
102 std::map<boost::asio::ip::tcp::endpoint, receive_data> receive_data_map;
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;
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;
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;
124 static const std::string MODULE_NAME;
126 static const int THREAD_DIVISION_UP_STREAM;
127 static const int THREAD_DIVISION_DOWN_STREAM;
129 static const int END_FLAG_OFF;
130 static const int END_FLAG_ON;
132 static const int ACCEPT_END_FLAG_OFF;
133 static const int ACCEPT_END_FLAG_ON;
135 static const int SORRY_FLAG_ON;
136 static const int SORRY_FLAG_OFF;
138 static const int SORRYSERVER_SWITCH_FLAG_OFF;
139 static const int SORRYSERVER_SWITCH_FLAG_ON;
141 static const int REALSERVER_SWITCH_FLAG_OFF;
142 static const int REALSERVER_SWITCH_FLAG_ON;
144 static const int EDIT_DIVISION_NO_EDIT;
145 static const int EDIT_DIVISION_EDIT;
147 static const int FORWARDED_FOR_OFF;
148 static const int FORWARDED_FOR_ON;
151 protocol_module_sessionless();
152 ~protocol_module_sessionless();
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);
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);
199 inline bool operator < (const protocol_module_sessionless::edit_data &lref, const protocol_module_sessionless::edit_data &rref)
201 return lref.insert_posission < rref.insert_posission;
204 class data_send_possible
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;
213 class data_send_disable
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 ;
222 class data_send_continue
225 inline bool operator()(const protocol_module_sessionless::send_status &send_status) {
226 return send_status.status == protocol_module_sessionless::SEND_CONTINUE;
233 inline bool operator()(const protocol_module_sessionless::send_status &send_status) {
234 return send_status.status == protocol_module_sessionless::SEND_NG;
241 inline bool operator()(const protocol_module_sessionless::send_status &send_status) {
242 return send_status.status == protocol_module_sessionless::SEND_OK;
246 class data_send_repeated
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;
256 class data_send_list_incorrect
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);
268 class rs_list_scoped_lock
271 boost::function< void(void) > rs_list_unlock;
273 rs_list_scoped_lock(boost::function< void(void) > inlist_lock,
274 boost::function< void(void) > inlist_unlock) {
276 rs_list_unlock = inlist_unlock;
278 ~rs_list_scoped_lock() {
284 #endif //PROTOCOL_MODULE_SESSIONLESS_H