2 * @file protocol_module_ip.h
3 * @brief protocol module ip 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
22 *register_replication_area_unlock
23 **********************************************************************/
25 #include <boost/thread/mutex.hpp>
26 #include "ip_protocol_module_base.h"
27 #include "ip_session_data_processor.h"
28 #include "ip_replication_data_processor.h"
30 #ifndef PROTOCOL_MODULE_IP_H
31 #define PROTOCOL_MODULE_IP_H
33 #define MAX_FORWARD_FOR_SIZE 36
34 #define MAX_OPTION_SIZE 128
35 #define MAX_IP_MODULE_BUFFER_SIZE (8190 + MAX_BUFFER_SIZE)
36 /* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */
37 #define GOLDEN_RATIO_PRIME 0x9e370001UL
42 class protocol_module_ip : public ip_protocol_module_base
53 typedef std::deque<std::pair<char*, size_t> > buffer_deque;
54 struct session_thread_data_ip
56 boost::thread::id thread_id;
57 boost::thread::id pair_thread_id;
63 size_t data_buffer_size;
66 size_t current_message_rest_size;
68 boost::array<char, MAX_FORWARD_FOR_SIZE> forwarded_for_buffer;
70 boost::asio::ip::tcp::endpoint client_endpoint;
71 DATA_STATE_TAG data_state;
72 EVENT_TAG last_status;
73 buffer_deque buffer_sequence;
76 typedef boost::shared_ptr<session_thread_data_ip> thread_data_ptr;
77 typedef std::map<boost::thread::id, thread_data_ptr>::iterator session_thread_data_map_it;
82 int realserver_connect_failed_max_count;
83 boost:: array<char,MAX_OPTION_SIZE> sorry_uri ;
84 std::map<boost::thread::id, thread_data_ptr> session_thread_data_map;
85 boost::mutex session_data_mutex;
86 boost::mutex session_thread_data_map_mutex;
88 ip_replication_data_processor* replication_data_processor;
89 ip_session_data_processor* ip_data_processor;
91 unsigned int l7vs_ip_service_calc_hash(const boost::asio::ip::tcp::endpoint& cl_endpoint)
93 unsigned int hash = 0;
94 if (cl_endpoint.address().is_v4())
96 hash= cl_endpoint.address().to_v4().to_ulong() * GOLDEN_RATIO_PRIME;
100 boost::asio::ip::address_v6::bytes_type v6_bytes = cl_endpoint.address().to_v6().to_bytes();
101 boost::asio::ip::address_v4::bytes_type v4_bytes = {{v6_bytes[12],v6_bytes[13],v6_bytes[14],v6_bytes[15]}};
102 boost::asio::ip::address_v4::address_v4 v4_address = boost::asio::ip::address_v4::address_v4(v4_bytes);
103 hash= v4_address.to_ulong() * GOLDEN_RATIO_PRIME;
106 return hash >> 32 - HASH_TABLE_BITS;
108 class rs_list_scoped_lock {
110 boost::function< void( void ) > rs_list_unlock;
112 rs_list_scoped_lock(boost::function< void( void ) > inlist_lock,
113 boost::function< void( void ) > inlist_unlock)
116 rs_list_unlock = inlist_unlock;
118 ~rs_list_scoped_lock() { rs_list_unlock(); }
122 static const std::string MODULE_NAME;
124 static const int THREAD_DIVISION_UP_STREAM;
125 static const int THREAD_DIVISION_DOWN_STREAM;
127 static const int END_FLAG_OFF;
128 static const int END_FLAG_ON;
130 static const int ACCEPT_END_FLAG_OFF;
131 static const int ACCEPT_END_FLAG_ON;
133 static const int SORRY_FLAG_ON;
134 static const int SORRY_FLAG_OFF;
136 static const int SWITCH_FLAG_OFF;
137 static const int SWITCH_FLAG_ON;
139 static const int FORWARDED_FOR_OFF;
140 static const int FORWARDED_FOR_ON;
143 protocol_module_ip();
144 ~protocol_module_ip();
147 void replication_interrupt();
148 void initialize(rs_list_itr_func_type inlist_begin,
149 rs_list_itr_func_type inlist_end,
150 rs_list_itr_next_func_type inlist_next,
151 boost::function< void( void ) > inlist_lock,
152 boost::function< void( void ) > inlist_unlock);
155 check_message_result check_parameter(const std::vector<std::string>& args);
156 check_message_result set_parameter(const std::vector<std::string>& args);
157 check_message_result add_parameter(const std::vector<std::string>& args);
158 void get_option_info(std::string& option);
159 void handle_rslist_update();
160 void register_schedule(tcp_schedule_func_type inschedule);
161 void register_schedule(udp_schedule_func_type inschedule);
162 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);
163 EVENT_TAG handle_session_finalize(const boost::thread::id up_thread_id, const boost::thread::id down_thread_id);
164 EVENT_TAG handle_accept(const boost::thread::id thread_id);
165 EVENT_TAG handle_client_recv(const boost::thread::id thread_id, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, const size_t recvlen);
166 EVENT_TAG handle_realserver_select(const boost::thread::id thread_id, boost::asio::ip::tcp::endpoint& rs_endpoint);
167 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);
168 EVENT_TAG handle_realserver_connect(const boost::thread::id thread_id, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, size_t& datalen);
169 EVENT_TAG handle_realserver_connection_fail(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint& rs_endpoint);
170 EVENT_TAG handle_realserver_send(const boost::thread::id thread_id);
171 EVENT_TAG handle_sorryserver_select(const boost::thread::id thread_id, boost::asio::ip::tcp::endpoint& sorry_endpoint);
172 EVENT_TAG handle_sorryserver_connect(const boost::thread::id thread_id, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, size_t& datalen);
173 EVENT_TAG handle_sorryserver_connection_fail(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint& sorry_endpoint);
174 EVENT_TAG handle_sorryserver_send(const boost::thread::id thread_id);
175 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);
176 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);
177 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);
178 EVENT_TAG handle_response_send_inform(const boost::thread::id thread_id);
179 EVENT_TAG handle_client_connection_check(const boost::thread::id thread_id, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, size_t& datalen);
180 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);
181 EVENT_TAG handle_client_send(const boost::thread::id thread_id);
182 EVENT_TAG handle_client_disconnect(const boost::thread::id thread_id);
183 EVENT_TAG handle_sorry_enable(const boost::thread::id thread_id);
184 EVENT_TAG handle_sorry_disable(const boost::thread::id thread_id);
185 EVENT_TAG handle_realserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint& rs_endpoint);
186 EVENT_TAG handle_sorryserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint& sorry_endpoint);
187 EVENT_TAG handle_realserver_close(const boost::thread::id thread_id, const boost::asio::ip::udp::endpoint& rs_endpoint);
188 bool get_data_from_recvbuffer(thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, const size_t recvlen);
189 bool put_data_into_sendbuffer(thread_data_ptr data_ptr, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t& datalen);
190 bool create_x_forwarded_for(const std::string& client_endpoint, const char* buffer,
191 const size_t buffer_len, size_t& x_forwarded_for_insert_pos,
192 std::string& x_forwarded_for_context);
202 #endif //PROTOCOL_MODULE_IP_H