OSDN Git Service

Merge pull request #36314 (suigintoh/ultramonkey-l7-v3/fix_signum_cast into master).
[ultramonkey-l7/ultramonkey-l7-v3.git] / l7vsd / include / virtualservice_element.h
1 /*!
2  * @file  virtualservice_element.h
3  * @brief use l7vscommand virtualservice_data prototype
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 #ifndef VIRTUALSERVICE_ELEMENT_H
26 #define VIRTUALSERVICE_ELEMENT_H
27
28 #include <vector>
29 #include <boost/foreach.hpp>
30 #include <boost/serialization/string.hpp>
31 #include <boost/serialization/vector.hpp>
32 #include <boost/serialization/list.hpp>
33 #include <boost/serialization/map.hpp>
34 #include <boost/algorithm/string.hpp>
35 #include <boost/format.hpp>
36 #include "realserver_element.h"
37 #include "endpoint.h"
38
39 namespace l7vs
40 {
41
42 // virtual service element includes.
43 class virtualservice_element
44 {
45 public:
46         typedef std::pair<std::string, std::string> access_log_rotate_arguments_pair_type;
47         typedef std::map<std::string, std::string> access_log_rotate_arguments_map_type;
48         enum SORRYSERVER_FWDMODE_TAG {
49                 FWD_NONE = 0,
50                 FWD_MASQ,
51                 FWD_TPROXY,
52         };
53
54         bool udpmode;
55         boost::asio::ip::tcp::endpoint tcp_accept_endpoint;
56         boost::asio::ip::udp::endpoint udp_recv_endpoint;
57         std::vector<realserver_element> realserver_vector;
58         std::string protocol_module_name;
59         std::vector<std::string> protocol_args;
60         std::string schedule_module_name;
61
62         long long sorry_maxconnection;
63         boost::asio::ip::tcp::endpoint sorry_endpoint;
64         int sorry_flag;
65         SORRYSERVER_FWDMODE_TAG sorry_fwdmode;
66
67         unsigned long long qos_upstream;
68         unsigned long long qos_downstream;
69         unsigned long long throughput_upstream;
70         unsigned long long throughput_downstream;
71         unsigned long long session_thread_pool_size;
72
73         std::string ssl_file_name;
74
75         int access_log_flag;
76         std::string access_log_file_name;
77         access_log_rotate_arguments_map_type access_log_rotate_arguments;
78         std::string access_log_rotate_key_info;
79         std::string access_log_rotate_verbose_info;
80
81         std::string protocol_module_for_indication_options;
82
83         int socket_option_tcp_defer_accept;
84         int socket_option_tcp_nodelay;
85         int socket_option_tcp_cork;
86         int socket_option_tcp_keepalive;
87         int socket_option_tcp_quickack;
88         std::string socket_option_string;
89
90         unsigned long long    http_total_count;
91         unsigned long long    http_get_count;
92         unsigned long long    http_post_count;
93
94         // constructor
95         virtualservice_element()
96                 :  udpmode(false),
97                    sorry_maxconnection(0LL),
98                    sorry_flag(0),
99                    sorry_fwdmode(FWD_NONE),
100                    qos_upstream(0ULL),
101                    qos_downstream(0ULL),
102                    throughput_upstream(0ULL),
103                    throughput_downstream(0ULL),
104                    session_thread_pool_size(0),
105                    access_log_flag(0),
106                    socket_option_tcp_defer_accept(0),
107                    socket_option_tcp_nodelay(0),
108                    socket_option_tcp_cork(0),
109                    socket_option_tcp_keepalive(0),
110                    socket_option_tcp_quickack(0),
111                    http_total_count(0ULL),
112                    http_get_count(0ULL),
113                    http_post_count(0ULL) {}
114
115         virtualservice_element(const virtualservice_element &in)
116                 :  udpmode(in.udpmode),
117                    tcp_accept_endpoint(in.tcp_accept_endpoint),
118                    udp_recv_endpoint(in.udp_recv_endpoint),
119                    protocol_module_name(in.protocol_module_name),
120                    schedule_module_name(in.schedule_module_name),
121                    sorry_maxconnection(in.sorry_maxconnection),
122                    sorry_endpoint(in.sorry_endpoint),
123                    sorry_flag(in.sorry_flag),
124                    sorry_fwdmode(in.sorry_fwdmode),
125                    qos_upstream(in.qos_upstream),
126                    qos_downstream(in.qos_downstream),
127                    throughput_upstream(in.throughput_upstream),
128                    throughput_downstream(in.throughput_downstream),
129                    session_thread_pool_size(in.session_thread_pool_size),
130                    ssl_file_name(in.ssl_file_name),
131                    access_log_flag(in.access_log_flag),
132                    access_log_file_name(in.access_log_file_name),
133                    access_log_rotate_key_info(in.access_log_rotate_key_info),
134                    access_log_rotate_verbose_info(in.access_log_rotate_verbose_info),
135                    protocol_module_for_indication_options(in.protocol_module_for_indication_options),
136                    socket_option_tcp_defer_accept(in.socket_option_tcp_defer_accept),
137                    socket_option_tcp_nodelay(in.socket_option_tcp_nodelay),
138                    socket_option_tcp_cork(in.socket_option_tcp_cork),
139                    socket_option_tcp_keepalive(in.socket_option_tcp_keepalive),
140                    socket_option_tcp_quickack(in.socket_option_tcp_quickack),
141                    socket_option_string(in.socket_option_string),
142                    http_total_count(in.http_total_count),
143                    http_get_count(in.http_get_count),
144                    http_post_count(in.http_post_count) {
145                 protocol_args.clear();
146                 BOOST_FOREACH(std::string str, in.protocol_args) {
147                         protocol_args.push_back(str);
148                 }
149                 realserver_vector.clear();
150                 BOOST_FOREACH(realserver_element elem, in.realserver_vector) {
151                         realserver_vector.push_back(elem);
152                 }
153                 access_log_rotate_arguments.clear();
154                 BOOST_FOREACH(access_log_rotate_arguments_pair_type pair, in.access_log_rotate_arguments) {
155                         access_log_rotate_arguments.insert(pair);
156                 }
157         }
158
159         virtualservice_element &operator=(const virtualservice_element &in) {
160                 udpmode = in.udpmode;
161                 tcp_accept_endpoint = in.tcp_accept_endpoint;
162                 udp_recv_endpoint = in.udp_recv_endpoint;
163                 protocol_module_name = in.protocol_module_name;
164                 schedule_module_name = in.schedule_module_name;
165                 sorry_maxconnection = in.sorry_maxconnection;
166                 sorry_endpoint = in.sorry_endpoint;
167                 sorry_flag = in.sorry_flag;
168                 sorry_fwdmode = in.sorry_fwdmode;
169                 qos_upstream = in.qos_upstream;
170                 qos_downstream = in.qos_downstream;
171                 throughput_upstream = in.throughput_upstream;
172                 throughput_downstream = in.throughput_downstream;
173                 session_thread_pool_size = in.session_thread_pool_size;
174                 access_log_flag = in.access_log_flag;
175                 ssl_file_name = in.ssl_file_name;
176                 access_log_file_name = in.access_log_file_name;
177                 protocol_module_for_indication_options = in.protocol_module_for_indication_options;
178                 access_log_rotate_key_info = in.access_log_rotate_key_info;
179                 access_log_rotate_verbose_info = in.access_log_rotate_verbose_info;
180                 socket_option_tcp_defer_accept = in.socket_option_tcp_defer_accept;
181                 socket_option_tcp_nodelay = in.socket_option_tcp_nodelay;
182                 socket_option_tcp_cork = in.socket_option_tcp_cork;
183                 socket_option_tcp_keepalive = in.socket_option_tcp_keepalive;
184                 socket_option_tcp_quickack = in.socket_option_tcp_quickack;
185                 socket_option_string = in.socket_option_string;
186                 http_total_count = in.http_total_count;
187                 http_get_count = in.http_get_count;
188                 http_post_count = in.http_post_count;
189                 protocol_args.clear();
190                 BOOST_FOREACH(std::string str, in.protocol_args) {
191                         protocol_args.push_back(str);
192                 }
193                 realserver_vector.clear();
194                 BOOST_FOREACH(realserver_element elem, in.realserver_vector) {
195                         realserver_vector.push_back(elem);
196                 }
197                 access_log_rotate_arguments.clear();
198                 BOOST_FOREACH(access_log_rotate_arguments_pair_type pair, in.access_log_rotate_arguments) {
199                         access_log_rotate_arguments.insert(pair);
200                 }
201                 return *this;
202         }
203
204         friend bool operator==(const virtualservice_element &elem1, const virtualservice_element &elem2) {
205                 if (elem1.udpmode == elem2.udpmode &&
206                     elem1.tcp_accept_endpoint == elem2.tcp_accept_endpoint &&
207                     elem1.udp_recv_endpoint == elem2.udp_recv_endpoint &&
208                     elem1.protocol_module_name == elem2.protocol_module_name &&
209                     elem1.sorry_maxconnection == elem2.sorry_maxconnection &&
210                     elem1.sorry_flag == elem2.sorry_flag &&
211                     elem1.sorry_fwdmode == elem2.sorry_fwdmode &&
212                     elem1.qos_upstream == elem2.qos_upstream &&
213                     elem1.qos_downstream == elem2.qos_downstream &&
214                     elem1.throughput_upstream == elem2.throughput_upstream &&
215                     elem1.throughput_downstream == elem2.throughput_downstream &&
216                     elem1.session_thread_pool_size == elem2.session_thread_pool_size &&
217                     elem1.access_log_flag == elem2.access_log_flag &&
218                     elem1.ssl_file_name == elem2.ssl_file_name &&
219                     elem1.access_log_file_name == elem2.access_log_file_name &&
220                     elem1.protocol_module_for_indication_options == elem2.protocol_module_for_indication_options &&
221                     elem1.access_log_rotate_key_info == elem2.access_log_rotate_key_info &&
222                     elem1.access_log_rotate_verbose_info == elem2.access_log_rotate_verbose_info &&
223                     elem1.socket_option_tcp_defer_accept == elem2.socket_option_tcp_defer_accept &&
224                     elem1.socket_option_tcp_nodelay == elem2.socket_option_tcp_nodelay &&
225                     elem1.socket_option_tcp_cork == elem2.socket_option_tcp_cork &&
226                     elem1.socket_option_tcp_keepalive == elem2.socket_option_tcp_keepalive &&
227                     elem1.socket_option_tcp_quickack == elem2.socket_option_tcp_quickack &&
228                     elem1.socket_option_string == elem2.socket_option_string &&
229                     elem1.http_total_count == elem2.http_total_count &&
230                     elem1.http_get_count == elem2.http_get_count &&
231                     elem1.http_post_count == elem2.http_post_count) {
232
233                         if (elem1.realserver_vector.size() != elem2.realserver_vector.size()) {
234                                 return false;
235                         }
236                         for (unsigned int i = 0; i < elem1.realserver_vector.size(); ++i) {
237                                 if (elem1.realserver_vector[i] != elem2.realserver_vector[i]) {
238                                         return false;
239                                 }
240                         }
241                         if (elem1.protocol_args.size() != elem2.protocol_args.size()) {
242                                 return false;
243                         }
244                         for (unsigned int i = 0; i < elem1.protocol_args.size(); ++i) {
245                                 if (elem1.protocol_args[i] != elem2.protocol_args[i]) {
246                                         return false;
247                                 }
248                         }
249                         if (elem1.access_log_rotate_arguments.size() != elem2.access_log_rotate_arguments.size()) {
250                                 return false;
251                         }
252                         BOOST_FOREACH(access_log_rotate_arguments_pair_type pair, elem1.access_log_rotate_arguments) {
253                                 access_log_rotate_arguments_map_type::const_iterator it = elem2.access_log_rotate_arguments.find(pair.first);
254                                 if (elem2.access_log_rotate_arguments.end() == it) {
255                                         return false;
256                                 }
257                                 if (it->second != pair.second) {
258                                         return false;
259                                 }
260                         }
261                         return true;
262                 }
263                 return false;
264         }
265
266         friend bool operator!=(const virtualservice_element &elem1, const virtualservice_element &elem2) {
267                 if (elem1.udpmode == elem2.udpmode &&
268                     elem1.tcp_accept_endpoint == elem2.tcp_accept_endpoint &&
269                     elem1.udp_recv_endpoint == elem2.udp_recv_endpoint &&
270                     elem1.protocol_module_name == elem2.protocol_module_name &&
271                     elem1.sorry_maxconnection == elem2.sorry_maxconnection &&
272                     elem1.sorry_flag == elem2.sorry_flag &&
273                     elem1.sorry_fwdmode == elem2.sorry_fwdmode &&
274                     elem1.qos_upstream == elem2.qos_upstream &&
275                     elem1.qos_downstream == elem2.qos_downstream &&
276                     elem1.throughput_upstream == elem2.throughput_upstream &&
277                     elem1.throughput_downstream == elem2.throughput_downstream &&
278                     elem1.session_thread_pool_size == elem2.session_thread_pool_size &&
279                     elem1.access_log_flag == elem2.access_log_flag &&
280                     elem1.ssl_file_name == elem2.ssl_file_name &&
281                     elem1.access_log_file_name == elem2.access_log_file_name &&
282                     elem1.protocol_module_for_indication_options == elem2.protocol_module_for_indication_options &&
283                     elem1.access_log_rotate_key_info == elem2.access_log_rotate_key_info &&
284                     elem1.access_log_rotate_verbose_info == elem2.access_log_rotate_verbose_info &&
285                     elem1.socket_option_tcp_defer_accept == elem2.socket_option_tcp_defer_accept &&
286                     elem1.socket_option_tcp_nodelay == elem2.socket_option_tcp_nodelay &&
287                     elem1.socket_option_tcp_cork == elem2.socket_option_tcp_cork &&
288                     elem1.socket_option_tcp_keepalive == elem2.socket_option_tcp_keepalive &&
289                     elem1.socket_option_tcp_quickack == elem2.socket_option_tcp_quickack &&
290                     elem1.socket_option_string == elem2.socket_option_string &&
291                     elem1.http_total_count == elem2.http_total_count &&
292                     elem1.http_get_count == elem2.http_get_count &&
293                     elem1.http_post_count == elem2.http_post_count) {
294
295                         if (elem1.realserver_vector.size() != elem2.realserver_vector.size()) {
296                                 return true;
297                         }
298                         for (unsigned int i = 0; i < elem1.realserver_vector.size(); ++i) {
299                                 if (elem1.realserver_vector[i] != elem2.realserver_vector[i]) {
300                                         return true;
301                                 }
302                         }
303                         if (elem1.protocol_args.size() != elem2.protocol_args.size()) {
304                                 return true;
305                         }
306                         for (unsigned int i = 0; i < elem1.protocol_args.size(); ++i) {
307                                 if (elem1.protocol_args[i] != elem2.protocol_args[i]) {
308                                         return true;
309                                 }
310                         }
311                         if (elem1.access_log_rotate_arguments.size() != elem2.access_log_rotate_arguments.size()) {
312                                 return true;
313                         }
314                         BOOST_FOREACH(access_log_rotate_arguments_pair_type pair, elem1.access_log_rotate_arguments) {
315                                 access_log_rotate_arguments_map_type::const_iterator it = elem2.access_log_rotate_arguments.find(pair.first);
316                                 if (elem2.access_log_rotate_arguments.end() == it) {
317                                         return true;
318                                 }
319                                 if (it->second != pair.second) {
320                                         return true;
321                                 }
322                         }
323                         return false;
324                 }
325                 return true;
326         }
327
328         friend bool operator<(const virtualservice_element &elem1, const virtualservice_element &elem2) {
329                 if (!elem1.udpmode && !elem2.udpmode) {
330                         return elem1.tcp_accept_endpoint < elem2.tcp_accept_endpoint;
331                 } else if (elem1.udpmode && elem2.udpmode) {
332                         return elem1.udp_recv_endpoint < elem2.udp_recv_endpoint;
333                 }
334                 return false;
335         }
336
337         template <typename Elem, typename Traits>
338         friend std::basic_ostream<Elem, Traits>& operator<<(std::basic_ostream<Elem, Traits>& os, const virtualservice_element &elem) {
339                 os << "virtualservice_element={";
340                 os << boost::format("udpmode=%s, "
341                                     "tcp_accept_endpoint=%s, "
342                                     "udp_recv_endpoint=%s, ")
343                    % elem.udpmode
344                    % elem.tcp_accept_endpoint
345                    % elem.udp_recv_endpoint;
346
347                 {
348                         unsigned int i = 0;
349                         BOOST_FOREACH(realserver_element rs_elem, elem.realserver_vector) {
350                                 os << boost::format("realserver_vector[%d]=") % i;
351                                 os << rs_elem;
352                                 os << ", ";
353                                 ++i;
354                         }
355                 }
356
357                 os << boost::format("protocol_module_name=%s, "
358                                     "schedule_module_name=%s, ")
359                    % elem.protocol_module_name
360                    % elem.schedule_module_name;
361
362                 std::stringstream access_log_rotate_arguments_stream;
363                 {
364                         unsigned int i = 0;
365                         BOOST_FOREACH(access_log_rotate_arguments_pair_type pair, elem.access_log_rotate_arguments) {
366                                 access_log_rotate_arguments_stream << boost::format("access_log_rotate_arguments[%d]=") % i;
367                                 access_log_rotate_arguments_stream << boost::format("{key=%s, value=%s}") % pair.first % pair.second;
368                                 access_log_rotate_arguments_stream << ", ";
369                                 ++i;
370                         }
371                 }
372
373                 std::string args = boost::algorithm::join(elem.protocol_args, " ");
374                 os << boost::format("protocol_args=%s, "
375                                     "sorry_maxconnection=%d, "
376                                     "sorry_endpoint=%s, "
377                                     "sorry_flag=%d, "
378                                     "sorry_fwdmode=%d, "
379                                     "qos_upstream=%d, "
380                                     "qos_downstream=%d, "
381                                     "throughput_upstream=%d, "
382                                     "throughput_downstream=%d, "
383                                     "session_thread_pool_size=%d, "
384                                     "access_log_flag=%d, "
385                                     "ssl_file_name=%s, "
386                                     "access_log_file_name=%s, "
387                                     "access_log_rotate_arguments=%s, "
388                                     "protocol_module_for_indication_options=%s, "
389                                     "access_log_rotate_key_info=%s, "
390                                     "access_log_rotate_verbose_info=%s, "
391                                     "socket_option_tcp_defer_accept=%d, "
392                                     "socket_option_tcp_nodelay=%d, "
393                                     "socket_option_tcp_cork=%d, "
394                                     "socket_option_tcp_keepalive=%d, "
395                                     "socket_option_tcp_quickack=%d, "
396                                     "socket_option_string=%s; "
397                                     "http_total_count=%d; "
398                                     "http_get_count=%d; "
399                                     "http_post_count=%d; }")
400                    % args
401                    % elem.sorry_maxconnection
402                    % elem.sorry_endpoint
403                    % elem.sorry_flag
404                    % elem.sorry_fwdmode
405                    % elem.qos_upstream
406                    % elem.qos_downstream
407                    % elem.throughput_upstream
408                    % elem.throughput_downstream
409                    % elem.session_thread_pool_size
410                    % elem.access_log_flag
411                    % elem.ssl_file_name
412                    % elem.access_log_file_name
413                    % access_log_rotate_arguments_stream.str()
414                    % elem.protocol_module_for_indication_options
415                    % elem.access_log_rotate_key_info
416                    % elem.access_log_rotate_verbose_info
417                    % elem.socket_option_tcp_defer_accept
418                    % elem.socket_option_tcp_nodelay
419                    % elem.socket_option_tcp_cork
420                    % elem.socket_option_tcp_keepalive
421                    % elem.socket_option_tcp_quickack
422                    % elem.socket_option_string
423                    % elem.http_total_count
424                    % elem.http_get_count
425                    % elem.http_post_count;
426
427                 return os;
428         }
429
430         const std::string get_fwdmode_str() {
431                 return sorry_fwdmode == FWD_MASQ   ? "Masq"
432                        : sorry_fwdmode == FWD_TPROXY ? "Tproxy"
433                        : "Unknown";
434         }
435
436 private:
437         friend class boost::serialization::access; //! friend boost serializable class
438         //! serializable
439         //! @brief using boost serializable. class serializable function.
440         //! @param[in] archive
441         //! @param[in] version
442         template <class Archive>
443         void serialize(Archive &ar, const unsigned int version) {
444                 ar &udpmode;
445                 ar &tcp_accept_endpoint;
446                 ar &udp_recv_endpoint;
447                 ar &realserver_vector;
448                 ar &protocol_module_name;
449                 ar &schedule_module_name;
450                 ar &protocol_args;
451                 ar &sorry_maxconnection;
452                 ar &sorry_endpoint;
453                 ar &sorry_flag;
454                 ar &sorry_fwdmode;
455                 ar &qos_upstream;
456                 ar &qos_downstream;
457                 ar &throughput_upstream;
458                 ar &throughput_downstream;
459                 ar &session_thread_pool_size;
460                 ar &access_log_flag;
461                 ar &ssl_file_name;
462                 ar &access_log_file_name;
463                 ar &access_log_rotate_arguments;
464                 ar &protocol_module_for_indication_options;
465                 ar &access_log_rotate_key_info;
466                 ar &access_log_rotate_verbose_info;
467                 ar &socket_option_tcp_defer_accept;
468                 ar &socket_option_tcp_nodelay;
469                 ar &socket_option_tcp_cork;
470                 ar &socket_option_tcp_keepalive;
471                 ar &socket_option_tcp_quickack;
472                 ar &socket_option_string;
473                 ar &http_total_count;
474                 ar &http_get_count;
475                 ar &http_post_count;
476         }
477 };
478
479 } //namespace l7vsd
480 #endif //L7VS_VIRTUALSERVICE_ELEMENT_H