3 * @brief protocol module of any protocol.
4 * @brief this module never keep session persistence.
6 * L7VSD: Linux Virtual Server for Layer7 Load Balancing
7 * Copyright (C) 2008 NTT COMWARE Corporation.
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 **********************************************************************/
26 #define __STDC_LIMIT_MACROS
30 #include "l7vs_service.h"
31 #include "l7vs_conn.h"
32 #include "l7vs_dest.h"
33 #include "l7vs_module.h"
34 #include "module_http.h"
36 #define SERVICE_ARG_MAXSIZE (512)
37 #define IP_SERVICE_NUMBER (128)
38 #define X_FORWARDED_FOR_LENGTH (48)
40 #define HASH_TABLE_BITS 8
41 #define HASH_TABLE_SIZE (1 << HASH_TABLE_BITS)
42 /* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */
43 #define GOLDEN_RATIO_PRIME 0x9e370001UL
45 struct l7vs_ip_service {
46 handle_t service_handle;
47 struct sockaddr_in dest[HASH_TABLE_SIZE];
48 int expire[HASH_TABLE_SIZE];
54 struct l7vs_ip_service_arg {
60 static void fini(void);
61 static int create(void*, handle_t);
62 static void* create_sa(struct l7vs_service_arg*);
63 static int compare(handle_t, handle_t);
64 static int select_dest(struct l7vs_service*, struct l7vs_conn*,
65 char*, size_t*, struct l7vs_dest**);
66 static int analyze_cldata(struct l7vs_service*, struct l7vs_conn*,
68 static int analyze_rsdata(struct l7vs_service*, struct l7vs_conn*,
70 static int destroy(handle_t);
71 static void destroy_sa(void**);
72 static int service_arg(struct l7vs_service_arg_multi*, handle_t);
73 static int parse(void*, int, char**);
75 static struct l7vs_ip_service *l7vs_protomod_ip_search_service(handle_t);
76 static struct l7vs_ip_service *l7vs_protomod_ip_create_service();
77 static struct l7vs_ip_service *l7vs_protomod_ip_create_temp_service();
79 static void l7vs_ip_service_c_str(char*, struct l7vs_ip_service*);
80 static void l7vs_ip_service_arg_c_str(char*, struct l7vs_ip_service_arg*);
81 unsigned int l7vs_ip_service_calc_hash(struct l7vs_conn*);
83 struct l7vs_ip_service *ip_service_list[IP_SERVICE_NUMBER];
85 static struct l7vs_protomod ip_protomod = {
89 1, /* fast schedule */
90 create, /* create function */
91 compare, /* compare function */
92 select_dest, /* select_dest function */
93 analyze_cldata, /* analyze_cldata function */
94 analyze_rsdata, /* analyze_rsdata function */
95 destroy, /* destroy function */
96 fini, /* fini function */
97 create_sa, /* create_sa function */
98 service_arg, /* service_arg function */
99 parse, /* parse function */
100 destroy_sa, /* destroy_sa function */
101 NULL, /* initialize function */
102 NULL, /* finalize function */
103 NULL, /* get_log_level function */
104 NULL, /* put_log_debug function */
105 NULL, /* put_log_info function */
106 NULL, /* put_log_warn function */
107 NULL, /* put_log_error function */
108 NULL /* put_log_fatal function */
112 * Protocol module initialize function. This function run when dlopen and dlsym at first time.
113 * @param[in] handle dlopen's handle
114 * @return l7vs_protomod struct
116 extern "C" struct l7vs_protomod *
119 struct l7vs_protomod* return_value = NULL;
121 /*-------- DEBUG LOG --------*/
122 if (ip_protomod.get_log_level != NULL &&
123 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
124 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,249,
125 "in_function: struct l7vs_protomod* init(void* handle): handle=%p", handle);
127 /*------ DEBUG LOG END ------*/
130 if (handle == NULL) {
131 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,217, "Arg(handle) is NULL pointer.");
135 /* initialize ip service list */
136 memset(ip_service_list, 0, sizeof(struct l7vs_ip_service *) * IP_SERVICE_NUMBER);
137 /* set dlopen's handle */
138 ip_protomod.handle = handle;
140 return_value = &ip_protomod;
143 /*-------- DEBUG LOG --------*/
144 if (ip_protomod.get_log_level != NULL &&
145 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
146 char protomod_str[DEBUG_STR_LEN] = {0};
147 l7vs_protomod_c_str(protomod_str, &ip_protomod);
148 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,250,
149 "out_function: struct l7vs_protomod* init(void* handle): return=&(%s)", protomod_str);
151 /*------ DEBUG LOG END ------*/
156 * Protocol module finalize function. free all ip service list just in case.
163 /* ip service list counter */
164 int service_number = 0;
166 /*-------- DEBUG LOG --------*/
167 if (ip_protomod.get_log_level != NULL &&
168 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
169 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,251, "in_function: void fini(void)");
171 /*------ DEBUG LOG END ------*/
173 /* check all ip service list */
174 for (service_number = 0; service_number < IP_SERVICE_NUMBER; ++service_number) {
175 /* if pointer that does not point NULL exists ... */
176 if (ip_service_list[service_number] != NULL) {
177 /*-------- DEBUG LOG --------*/
178 if (ip_protomod.get_log_level != NULL &&
179 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_SYSTEM_MEMORY)) {
180 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,58, "free: %p",
181 ip_service_list[service_number]);
183 /*------ DEBUG LOG END ------*/
185 /* free and points NULL */
186 free(ip_service_list[service_number]);
187 ip_service_list[service_number] = NULL;
191 /*-------- DEBUG LOG --------*/
192 if (ip_protomod.get_log_level != NULL &&
193 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
194 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,252, "out_function: void fini(void)");
196 /*------ DEBUG LOG END ------*/
200 * Create ip service struct.
201 * @param[in] ip_arg ip service argument struct
202 * @param[in] service_handle a unique service ID
203 * @retval 0 successfully create ip service.
204 * @retval -1 some errors occur.
207 create(void *ip_arg, handle_t service_handle)
209 struct l7vs_ip_service *ip_service;
210 struct l7vs_ip_service_arg *ip_service_arg;
211 int return_value = 0;
213 /*-------- DEBUG LOG --------*/
214 if (ip_protomod.get_log_level != NULL &&
215 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
216 char ip_arg_str[DEBUG_STR_LEN] = {0};
217 l7vs_ip_service_arg_c_str(ip_arg_str, (struct l7vs_ip_service_arg*) ip_arg);
218 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,253,
219 "in_function: int create(void* ip_arg, handle_t service_handle):ip_arg=&(%s), "
220 "service_handle=%d", ip_arg_str, service_handle);
222 /*------ DEBUG LOG END ------*/
225 if (ip_arg == NULL) {
226 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,218, "Arg(ip_arg) is NULL pointer.");
232 if (service_handle != TEMP_SERVICEHANDLE) {
233 /* search empty ip service list and create ip service */
234 ip_service = l7vs_protomod_ip_create_service();
236 /* create temporary ip service */
237 ip_service = l7vs_protomod_ip_create_temp_service();
240 /*-------- DEBUG LOG --------*/
241 if (ip_protomod.get_log_level != NULL &&
242 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
243 char ip_str[DEBUG_STR_LEN] = {0};
244 l7vs_ip_service_c_str(ip_str, ip_service);
245 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,254, "pointer assign: ip_service=&(%s)",
248 /*------ DEBUG LOG END ------*/
250 if (ip_service == NULL) {
251 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,219, "Could not make ip service.");
256 ip_service_arg = (struct l7vs_ip_service_arg *) ip_arg;
258 /* set service handle */
259 ip_service->service_handle = service_handle;
261 ip_service->timeout = ip_service_arg->timeout;
262 /* set x-forwarded-for flag */
263 ip_service->forwarded_for = ip_service_arg->forwarded_for;
265 ip_service->reschedule = ip_service_arg->reschedule;
268 /*-------- DEBUG LOG --------*/
269 if (ip_protomod.get_log_level != NULL &&
270 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
271 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,255,
272 "out_function: int create(void* ip_arg, handle_t service_handle):return_value=%d",
275 /*------ DEBUG LOG END ------*/
281 * Create ip service argument struct.
282 * @param[out] srv_arg service argument struct
283 * @return ip service argument struct
286 create_sa(struct l7vs_service_arg *srv_arg)
288 struct l7vs_ip_service_arg *ip_service_arg;
290 /*-------- DEBUG LOG --------*/
291 if (ip_protomod.get_log_level != NULL &&
292 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
293 char service_arg_str[DEBUG_STR_LEN] = {0};
294 l7vs_service_arg_c_str(service_arg_str, srv_arg);
295 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,256,
296 "in_function: void* create_sa(struct l7vs_service_arg* srv_arg):srv_arg=&(%s)",
299 /*------ DEBUG LOG END ------*/
302 if (srv_arg == NULL) {
303 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,220, "Arg(srv_arg) is NULL pointer.");
304 ip_service_arg = NULL;
308 /* create ip service argument struct */
309 ip_service_arg = (struct l7vs_ip_service_arg *) calloc(1, sizeof(struct l7vs_ip_service_arg));
311 /*-------- DEBUG LOG --------*/
312 if (ip_protomod.get_log_level != NULL &&
313 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_SYSTEM_MEMORY)) {
314 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,59, "calloc: addr=%p, size=%ld",
315 ip_service_arg, (unsigned long int) sizeof(struct l7vs_ip_service_arg));
317 /*------ DEBUG LOG END ------*/
319 if (ip_service_arg == NULL) {
320 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,53, "Could not allocate memory.");
324 /* set ip service argument size and protomod name "ip" */
325 srv_arg->len = sizeof(struct l7vs_ip_service_arg);
326 strcpy(srv_arg->protomod, ip_protomod.modname);
329 /*-------- DEBUG LOG --------*/
330 if (ip_protomod.get_log_level != NULL &&
331 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
332 char ip_service_arg_str[DEBUG_STR_LEN] = {0};
333 l7vs_ip_service_arg_c_str(ip_service_arg_str, ip_service_arg);
334 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,257,
335 "out_function: void* create_sa(struct l7vs_service_arg* srv_arg):return_value=&(%s)",
338 /*------ DEBUG LOG END ------*/
340 return (void *) ip_service_arg;
344 * Compare two service.
345 * @param[in] srv_handle1 one of a unique service ID
346 * @param[in] srv_handle2 one of a unique service ID
347 * @retval 0 they matched perfectly.
348 * @retval -1 they are different.
351 compare(handle_t srv_handle1, handle_t srv_handle2)
353 int return_value = 0;
355 /*-------- DEBUG LOG --------*/
356 if (ip_protomod.get_log_level != NULL &&
357 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
358 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,258,
359 "in_function: int compare(handle_t srv_handle1, handle_t srv_handle2):"
360 "srv_handle1=%u, srv_handle2=%u", srv_handle1, srv_handle2);
361 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,259,
362 "out_function: int compare(handle_t srv_handle1, handle_t srv_handle2):return_value=%d",
365 /*------ DEBUG LOG END ------*/
371 * Do not check the request packet.
372 * @param[in] srv service struct include service handle, protocol module and schedule module.
373 * @param[in] conn connection data.
374 * @param[in] request packet data from client
375 * @param[in] len length of packet data
376 * @param[out] dest destination (real server) list
377 * @retval 0 successfully check packet data
378 * @retval -1 some errors occur.
381 select_dest(struct l7vs_service *srv, struct l7vs_conn *conn,
382 char *request, size_t *len, struct l7vs_dest **dest)
384 struct l7vs_ip_service *ip_service;
385 struct l7vs_dest destination;
387 int return_value = 0;
391 /*-------- DEBUG LOG --------*/
392 if (ip_protomod.get_log_level != NULL &&
393 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
394 char srv_str[DEBUG_STR_LEN] = {0};
395 char conn_str[DEBUG_STR_LEN] = {0};
396 char dest_str[DEBUG_STR_LEN] = {0};
397 char len_str[DEBUG_STR_LEN] = {0};
398 l7vs_service_c_str(srv_str, srv);
399 l7vs_conn_c_str(conn_str, conn);
401 l7vs_dest_c_str(dest_str, *dest);
404 strncpy(dest_str, "NULL", DEBUG_STR_LEN);
407 snprintf(len_str, DEBUG_STR_LEN, "%lu", (unsigned long int) *len);
410 strncpy(len_str, "NULL", DEBUG_STR_LEN);
412 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,260,
413 "in_function: int select_dest(struct l7vs_service* srv, struct l7vs_conn* conn, "
414 "char* request, size_t* len, struct l7vs_dest** dest):srv=&(%s), conn=&(%s), "
415 "request=\"%s\", len=&(%s), dest=&(&(%s))",
416 srv_str, conn_str, request, len_str, dest_str);
418 /*------ DEBUG LOG END ------*/
422 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,221, "Arg(srv) is NULL pointer.");
424 goto select_dest_out;
426 if (srv->pm == NULL) {
427 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,222, "Arg(srv->pm) is NULL pointer.");
429 goto select_dest_out;
431 if (request == NULL) {
432 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,223, "Arg(request) is NULL pointer.");
434 goto select_dest_out;
437 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,224, "Arg(len) is NULL pointer.");
439 goto select_dest_out;
442 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,225, "Arg(dest) is NULL pointer.");
444 goto select_dest_out;
447 /* search service that has such a service ID */
448 ip_service = l7vs_protomod_ip_search_service(srv->handle);
450 /*-------- DEBUG LOG --------*/
451 if (ip_protomod.get_log_level != NULL &&
452 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
453 char ip_str[DEBUG_STR_LEN] = {0};
454 l7vs_ip_service_c_str(ip_str, ip_service);
455 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,261, "pointer assign: ip_service=&(%s)",
458 /*------ DEBUG LOG END ------*/
460 if (ip_service == NULL) {
461 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,227, "Could not find such service handle's ip service.");
463 goto select_dest_out;
466 /* initialize protocol module ... clear destination list */
467 ret = srv->pm->initialize(srv, conn, request, *len, dest);
469 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,228, "Could not initialize protomod.");
471 goto select_dest_out;
475 hash = l7vs_ip_service_calc_hash(conn);
476 if ( ip_service->dest[hash].sin_addr.s_addr
477 && ip_service->dest[hash].sin_port
478 && (ip_service->timeout == 0 || now < ip_service->expire[hash])
480 destination.addr.sin_addr.s_addr = ip_service->dest[hash].sin_addr.s_addr;
481 destination.addr.sin_port = ip_service->dest[hash].sin_port;
482 *dest = &destination;
486 ret = srv->pm->finalize(srv, conn, request, *len, dest, ip_service->reschedule);
488 PUT_LOG_INFO(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,17, "Could not finalize protomod. (Realserver decision failure)");
490 goto select_dest_out;
494 /*-------- DEBUG LOG --------*/
495 if (ip_protomod.get_log_level != NULL &&
496 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
497 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,262,
498 "out_function: int select_dest(struct l7vs_service* srv, struct l7vs_conn* conn, "
499 "char* request, size_t* len, struct l7vs_dest** dest):return_value=%d",
502 /*------ DEBUG LOG END ------*/
508 * Analyze and modify client packet
509 * @param[in] srv service struct include service handle, protocol module and schedule module.
510 * @param[in] conn connection data.
511 * @param[in] request packet data from client
512 * @param[in] len length of packet data
513 * @retval 0 successfully check packet data
514 * @retval -1 some errors occur.
517 analyze_cldata(struct l7vs_service *srv, struct l7vs_conn *conn,
518 char *request, size_t *len)
520 struct l7vs_ip_service *ip_service;
521 struct l7vs_dest destination;
523 char* x_forwarded_value;
524 char* next_line = NULL;
525 char x_forwarded_for_header[X_FORWARDED_FOR_LENGTH];
527 int return_value = 0;
529 /*-------- DEBUG LOG --------*/
530 if (ip_protomod.get_log_level != NULL &&
531 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
532 char srv_str[DEBUG_STR_LEN] = {0};
533 char conn_str[DEBUG_STR_LEN] = {0};
534 char len_str[DEBUG_STR_LEN] = {0};
535 l7vs_service_c_str(srv_str, srv);
536 l7vs_conn_c_str(conn_str, conn);
538 snprintf(len_str, DEBUG_STR_LEN, "%lu", (unsigned long int) *len);
541 strncpy(len_str, "NULL", DEBUG_STR_LEN);
543 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,260,
544 "in_function: int analyze_cldata(struct l7vs_service* srv, struct l7vs_conn* conn, "
545 "char* request, size_t* len):srv=&(%s), conn=&(%s), request=\"%s\", len=&(%s)",
546 srv_str, conn_str, request, len_str);
548 /*------ DEBUG LOG END ------*/
552 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,221, "Arg(srv) is NULL pointer.");
554 goto analyze_cldata_out;
556 if (srv->pm == NULL) {
557 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,222, "Arg(srv->pm) is NULL pointer.");
559 goto analyze_cldata_out;
561 if (request == NULL) {
562 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,223, "Arg(request) is NULL pointer.");
564 goto analyze_cldata_out;
567 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,224, "Arg(len) is NULL pointer.");
569 goto analyze_cldata_out;
572 /* search service that has such a service ID */
573 ip_service = l7vs_protomod_ip_search_service(srv->handle);
575 /*-------- DEBUG LOG --------*/
576 if (ip_protomod.get_log_level != NULL &&
577 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
578 char ip_str[DEBUG_STR_LEN] = {0};
579 l7vs_ip_service_c_str(ip_str, ip_service);
580 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,261, "pointer assign: ip_service=&(%s)",
583 /*------ DEBUG LOG END ------*/
585 if (ip_service == NULL) {
586 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,227, "Could not find such service handle's ip service.");
588 goto analyze_cldata_out;
591 /* set X-Forwarded-For field */
592 if (ip_service->forwarded_for) {
595 if (http_check_request_method(request, &uri_len) == NULL)
596 goto analyze_cldata_out;
598 x_forwarded_value = http_search_header_field(request, "X-Forwarded-For");
600 /* already exists X-Forwarded-For field */
601 if (x_forwarded_value) {
602 next_line = http_skip_header_line(x_forwarded_value);
603 /* backtrack to look up insert point */
605 next_line--; // *next_line == '\n'
606 if (*(next_line - 1) == '\r') {
609 /* append client IP address */
610 snprintf(x_forwarded_for_header, X_FORWARDED_FOR_LENGTH, ", %s", inet_ntoa(conn->caddr.sin_addr));
614 /* not exists X-Forwarded-For field */
616 /* construct new X-Forwarded-For header item */
617 snprintf(x_forwarded_for_header, X_FORWARDED_FOR_LENGTH, "X-Forwarded-For: %s\r\n", inet_ntoa(conn->caddr.sin_addr));
619 next_line = http_skip_header_line(request);
622 /* when insert point exist */
623 if (next_line != NULL) {
624 offset_length = (int) (next_line - request);
626 /* insert X-Forwarded-For header field */
627 http_insert_field(request, offset_length, x_forwarded_for_header, *len);
629 /* add header length */
630 *len += strlen(x_forwarded_for_header);
635 /*-------- DEBUG LOG --------*/
636 if (ip_protomod.get_log_level != NULL &&
637 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
638 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,262,
639 "out_function: int analyze_cldata(struct l7vs_service* srv, struct l7vs_conn* conn, "
640 "char* request, size_t* len):return_value=%d", return_value);
642 /*------ DEBUG LOG END ------*/
648 * Calculate source IP address's hash value and regist it with destination IP address.
649 * @param[in] srv service struct include service handle, protocol module and schedule module.
650 * @param[in] conn connection data.
651 * @param[in] response packet data from real server
652 * @param[in] len length of packet data. it will be lengthened.
653 * @retval 0 successfully check packet data.
654 * @retval -1 some errors occur.
657 analyze_rsdata(struct l7vs_service *srv, struct l7vs_conn *conn,
658 char *response, size_t *len)
660 struct l7vs_ip_service *ip_service;
662 int return_value = 0;
665 /*-------- DEBUG LOG --------*/
666 if (ip_protomod.get_log_level != NULL &&
667 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
668 char srv_str[DEBUG_STR_LEN] = {0};
669 char conn_str[DEBUG_STR_LEN] = {0};
670 char len_str[DEBUG_STR_LEN] = {0};
671 l7vs_service_c_str(srv_str, srv);
672 l7vs_conn_c_str(conn_str, conn);
674 snprintf(len_str, DEBUG_STR_LEN, "%lu", (unsigned long int) *len);
677 strncpy(len_str, "NULL", DEBUG_STR_LEN);
679 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,263,
680 "in_function: int analyze_rsdata(struct l7vs_service* srv, struct l7vs_conn* conn, "
681 "char* response, size_t* len):srv=&(%s), conn=&(%s), response=\"%s\", len=&(%s)",
682 srv_str, conn_str, response, len_str);
684 /*------ DEBUG LOG END ------*/
688 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,229, "Arg(srv) is NULL pointer.");
690 goto analyze_rsdata_out;
693 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,230, "Arg(conn) is NULL pointer.");
695 goto analyze_rsdata_out;
697 if (conn->dest == NULL) {
698 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,231, "Arg(conn->dest) is NULL pointer.");
700 goto analyze_rsdata_out;
702 if (response == NULL) {
703 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,232, "Arg(response) is NULL pointer.");
705 goto analyze_rsdata_out;
708 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,233, "Arg(len) is NULL pointer.");
710 goto analyze_rsdata_out;
713 /* sorry flag check */
714 if (conn->sorry_conn_flag == 1) {
715 /*-------- DEBUG LOG --------*/
716 if (ip_protomod.get_log_level != NULL &&
717 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
718 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,264, "Response from sorry server.");
720 /*------ DEBUG LOG END ------*/
721 goto analyze_rsdata_out;
724 /* search service that has such a service ID */
725 ip_service = l7vs_protomod_ip_search_service(srv->handle);
727 /*-------- DEBUG LOG --------*/
728 if (ip_protomod.get_log_level != NULL &&
729 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
730 char ip_str[DEBUG_STR_LEN];
731 l7vs_ip_service_c_str(ip_str, ip_service);
732 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,265, "pointer assign: ip_service=&(%s)",
735 /*------ DEBUG LOG END ------*/
737 if (ip_service == NULL) {
738 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,234,
739 "Could not find such service handle's ip service.");
741 goto analyze_rsdata_out;
744 hash = l7vs_ip_service_calc_hash(conn);
745 memcpy(&ip_service->dest[hash], &conn->dest->addr, sizeof(struct sockaddr_in));
746 if (ip_service->timeout)
748 ip_service->expire[hash] = now + ip_service->timeout;
751 /*-------- DEBUG LOG --------*/
752 if (ip_protomod.get_log_level != NULL &&
753 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
754 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,266,
755 "out_function: int analyze_rsdata(struct l7vs_service* srv, struct l7vs_conn* conn, "
756 "char* response, size_t* len):return_value=%d", return_value);
758 /*------ DEBUG LOG END ------*/
765 * @param[in] srv_handle a unique service ID
766 * @retval 0 successfully check packet data.
767 * @retval -1 some errors occur.
770 destroy(handle_t srv_handle)
772 /* ip service list counter */
773 int service_number = 0;
775 int return_value = 0;
777 /*-------- DEBUG LOG --------*/
778 if (ip_protomod.get_log_level != NULL &&
779 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
780 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,267,
781 "in_function: int destroy(handle_t srv_handle):srv_handle=%u",
784 /*------ DEBUG LOG END ------*/
786 /* check all ip service list */
787 for (service_number = 0; service_number < IP_SERVICE_NUMBER; ++service_number) {
788 /* found ip service that has srv_handle */
789 if (ip_service_list[service_number] != NULL &&
790 ip_service_list[service_number]->service_handle == srv_handle) {
793 free(ip_service_list[service_number]);
794 ip_service_list[service_number] = NULL;
801 /* ip service was not found */
802 if (free_flag == 0) {
803 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,235, "Could not find such service handle's ip service.");
809 /*-------- DEBUG LOG --------*/
810 if (ip_protomod.get_log_level != NULL &&
811 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
812 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,268,
813 "out_function: int destroy(handle_t srv_handle):return_value=%d",
816 /*------ DEBUG LOG END ------*/
822 * Destroy ip service argument
823 * @param[in] ip_arg ip service argument
827 destroy_sa(void **ip_arg)
829 /*-------- DEBUG LOG --------*/
830 if (ip_protomod.get_log_level != NULL &&
831 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
832 char ip_arg_str[DEBUG_STR_LEN] = {0};
833 if (ip_arg != NULL) {
834 l7vs_ip_service_arg_c_str(ip_arg_str, (struct l7vs_ip_service_arg*) *ip_arg);
837 strncpy(ip_arg_str, "NULL", DEBUG_STR_LEN);
839 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,269,
840 "in_function: void destroy_sa(void** ip_arg):ip_arg=&(&(%s))",
843 /*------ DEBUG LOG END ------*/
846 if (ip_arg == NULL) {
847 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,236, "Arg(ip_arg) is NULL pointer.");
849 else if (*ip_arg == NULL) {
850 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,237, "Arg(*ip_arg) is NULL pointer.");
853 /*-------- DEBUG LOG --------*/
854 if (ip_protomod.get_log_level != NULL &&
855 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_SYSTEM_MEMORY)) {
856 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,60, "free: %p",
859 /*------ DEBUG LOG END ------*/
862 free((struct l7vs_ip_service_arg*) *ip_arg);
866 /*-------- DEBUG LOG --------*/
867 if (ip_protomod.get_log_level != NULL &&
868 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
869 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,270,
870 "out_function: void destroy_sa(void** ip_arg)");
872 /*------ DEBUG LOG END ------*/
876 * Create strings for service list of l7vsadm
877 * @param[out] srv_arg service argument struct
878 * @param[in] srv_handle a unique service ID
879 * @retval 0 successfully create strings
880 * @retval -1 some errors occur.
883 service_arg(struct l7vs_service_arg_multi *srv_arg_mt, handle_t srv_handle)
885 struct l7vs_ip_service *ip_service;
886 struct l7vs_ip_service_arg c_sarg;
887 char ip_argument[SERVICE_ARG_MAXSIZE];
888 int return_value = 0;
890 /*-------- DEBUG LOG --------*/
891 if (ip_protomod.get_log_level != NULL &&
892 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
893 char srv_arg_mt_str[DEBUG_STR_LEN] = {0};
894 l7vs_service_arg_multi_c_str(srv_arg_mt_str, srv_arg_mt);
895 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,271,
896 "in_function: int service_arg(struct l7vs_service_arg_multi* srv_arg_mt, "
897 "handle_t srv_handle):srv_arg_mt=&(%s), srv_handle=%u",
898 srv_arg_mt_str, srv_handle);
900 /*------ DEBUG LOG END ------*/
903 if (srv_arg_mt == NULL) {
904 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,238, "Arg(srv_arg_mt) is NULL pointer.");
906 goto service_arg_out;
909 /* search service that has such a service ID */
910 ip_service = l7vs_protomod_ip_search_service(srv_handle);
912 /*-------- DEBUG LOG --------*/
913 if (ip_protomod.get_log_level != NULL &&
914 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
915 char ip_str[DEBUG_STR_LEN] = {0};
916 l7vs_ip_service_c_str(ip_str, ip_service);
917 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,272, "pointer assign: ip_service=&(%s)",
920 /*------ DEBUG LOG END ------*/
922 if (ip_service == NULL) {
923 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,239, "Could not find such service handle's ip service.");
925 goto service_arg_out;
928 /* initialize argument strings */
929 memset(ip_argument, 0, SERVICE_ARG_MAXSIZE);
931 /* set ip args to service argument struct */
932 srv_arg_mt->srv_arg.reschedule = ip_service->reschedule;
934 /* create long argument (l7vsadm option -L/-l) */
935 strncpy(srv_arg_mt->srv_arg.protomod_key_string, "", 256);
937 /* create verbose argument (l7vsadm option -V/-v) */
938 if (ip_service->forwarded_for) {
939 snprintf(ip_argument, SERVICE_ARG_MAXSIZE, "--timeout %d --forwarded-for", ip_service->timeout);
941 snprintf(ip_argument, SERVICE_ARG_MAXSIZE, "--timeout %d", ip_service->timeout);
943 strncpy(srv_arg_mt->srv_arg.protomod_opt_string, ip_argument, 512);
945 c_sarg.reschedule = ip_service->reschedule;
947 memcpy(srv_arg_mt->protomod_arg, &c_sarg, sizeof(struct l7vs_ip_service_arg));
949 /*-------- DEBUG LOG --------*/
950 if (ip_protomod.get_log_level != NULL &&
951 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
952 char ip_arg_str[DEBUG_STR_LEN] = {0};
953 l7vs_ip_service_arg_c_str(ip_arg_str, &c_sarg);
954 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,273,
955 "pointer assign: srv_arg_mt->protomod_arg=&(%s)", ip_arg_str);
957 /*------ DEBUG LOG END ------*/
960 /*-------- DEBUG LOG --------*/
961 if (ip_protomod.get_log_level != NULL &&
962 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
963 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,274,
964 "out_function: int service_arg(struct l7vs_service_arg_multi* srv_arg_mt, "
965 "handle_t srv_handle):return_value=%d", return_value);
967 /*------ DEBUG LOG END ------*/
973 * Parse l7vsadm options to ip argument
974 * @param[out] ip_arg ip service argument struct
975 * @param[in] argc number of l7vsadm argument
976 * @param[in] argv l7vsadm argument list
977 * @retval 0 successfully parse argument
978 * @retval -1 some errors occur.
981 parse(void *ip_arg, int argc, char *argv[])
983 struct l7vs_ip_service_arg *ip_service_arg;
984 static struct option opt[] = {
985 {"timeout", required_argument, NULL, 'T'},
986 {"forwarded-for", no_argument, NULL, 'F'},
987 {"reschedule", no_argument, NULL, 'R'},
988 {"no-reschedule", no_argument, NULL, 'N'},
992 int return_value = 0;
993 int timeout_flag = 0;
994 int forwarded_for_flag = 0;
995 int reschedule_flag = 0;
996 unsigned long buffer;
998 /*-------- DEBUG LOG --------*/
999 if (ip_protomod.get_log_level != NULL &&
1000 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1002 char argv_str[DEBUG_STR_LEN] = {0};
1003 char ip_arg_str[DEBUG_STR_LEN] = {0};
1004 l7vs_ip_service_arg_c_str(ip_arg_str, (struct l7vs_ip_service_arg*) ip_arg);
1007 snprintf(argv_str, DEBUG_STR_LEN, "NULL");
1009 for (i = 0; i < argc; i++) {
1010 snprintf(argv_str, DEBUG_STR_LEN, "%sargv[%d]=\"%s\", ", argv_str, i, argv[i]);
1012 i = strnlen(argv_str, DEBUG_STR_LEN);
1014 argv_str[i - 2] = '\0';
1016 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,275,
1017 "in_function: int parse(void* ip_arg, int argc, char* argv[]):ip_arg=&(%s), "
1018 "argc=%d, %s", ip_arg_str, argc, argv_str);
1020 /*------ DEBUG LOG END ------*/
1023 if (ip_arg == NULL) {
1024 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,240, "Arg(ip_arg) is NULL pointer.");
1029 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,241, "Arg(argv) is NULL pointer.");
1034 ip_service_arg = (struct l7vs_ip_service_arg *) ip_arg;
1037 /* check all argument */
1038 while ((c = getopt_long(argc, argv, "T:FRN", opt, NULL)) != -1) {
1040 /* --timeout / -T */
1042 if (sscanf(optarg, "%lu", &buffer) == 0) {
1043 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,107,
1044 "-T/--timeout option value '%s' is invalid.", optarg);
1048 if (buffer > INT_MAX) {
1049 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,108,
1050 "-T/--timeout option value '%s' is too large.", optarg);
1055 ip_service_arg->timeout = buffer;
1058 /* --forwarded-for / -F */
1060 /* x-forwarded-for on */
1061 ip_service_arg->forwarded_for = 1;
1062 forwarded_for_flag++;
1064 /* --reschedule / -R */
1067 ip_service_arg->reschedule = 1;
1070 /* --no-reschedule / -N */
1072 /* reschedule off */
1073 ip_service_arg->reschedule = 0;
1078 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,242, "Option error.");
1084 /* when set both -R and -N at the same time */
1085 if (reschedule_flag > 1) {
1086 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,243,
1087 "You have to choose either of reschdule or no-reschedule.");
1092 if (timeout_flag > 1) {
1093 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,113,
1094 "Cannot set multiple option '--timeout/-T'.");
1098 /* set default options */
1099 if (timeout_flag == 0) {
1100 ip_service_arg->timeout = 3600;
1102 /* set default no reschedule */
1103 if (reschedule_flag == 0) {
1104 ip_service_arg->reschedule = 0;
1106 /* set default no forwarded_for */
1107 if (forwarded_for_flag == 0) {
1108 ip_service_arg->forwarded_for = 0;
1112 /*-------- DEBUG LOG --------*/
1113 if (ip_protomod.get_log_level != NULL &&
1114 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1115 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,276,
1116 "out_function: int parse(void* ip_arg, int argc, char* argv[]):return_value=%d",
1119 /*------ DEBUG LOG END ------*/
1121 return return_value;
1125 * Search ip service from ip service list using service handle
1126 * @param[in] service_handle a unique service ID
1127 * @return ip service struct when service was found. NULL when service was not found.
1129 static struct l7vs_ip_service *
1130 l7vs_protomod_ip_search_service(handle_t service_handle)
1132 /* ip service list counter */
1133 int service_number = 0;
1134 struct l7vs_ip_service* return_value = NULL;
1136 /*-------- DEBUG LOG --------*/
1137 if (ip_protomod.get_log_level != NULL &&
1138 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1139 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,277,
1140 "in_function: struct l7vs_ip_service* l7vs_protomod_ip_search_service(handle_t service_handle):"
1141 "service_handle=%d", service_handle);
1143 /*------ DEBUG LOG END ------*/
1145 /* check all ip service list */
1146 for (service_number = 0; service_number < IP_SERVICE_NUMBER; ++service_number) {
1147 /* found the service has same service handle */
1148 if (ip_service_list[service_number] != NULL &&
1149 ip_service_list[service_number]->service_handle == service_handle) {
1150 return ip_service_list[service_number];
1154 /*-------- DEBUG LOG --------*/
1155 if (ip_protomod.get_log_level != NULL &&
1156 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1157 char ssl_str[DEBUG_STR_LEN] = {0};
1158 l7vs_ip_service_c_str(ssl_str, return_value);
1159 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,278,
1160 "out_function: struct l7vs_ip_service* l7vs_protomod_ip_search_service(handle_t service_handle):"
1161 "return_value=&(%s)", ssl_str);
1163 /*------ DEBUG LOG END ------*/
1165 return return_value;
1169 * Create ip service.
1171 * @return ip service struct when create a service. NULL when cannot create service.
1173 static struct l7vs_ip_service *
1174 l7vs_protomod_ip_create_service()
1176 /* ip service list counter */
1177 int service_number = 0;
1178 struct l7vs_ip_service* return_value = NULL;
1180 /*-------- DEBUG LOG --------*/
1181 if (ip_protomod.get_log_level != NULL &&
1182 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1183 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,279,
1184 "in_function: struct l7vs_ip_service* l7vs_protomod_ip_create_service()");
1186 /*------ DEBUG LOG END ------*/
1188 /* check all ip service list */
1189 for (service_number = 0; service_number < IP_SERVICE_NUMBER - 1; ++service_number) {
1190 /* if pointer that does not point NULL exists ... */
1191 if (ip_service_list[service_number] == NULL) {
1192 /* create a service at empty pointer */
1193 ip_service_list[service_number] = (struct l7vs_ip_service *) calloc(1, sizeof(struct l7vs_ip_service));
1195 /*-------- DEBUG LOG --------*/
1196 if (ip_protomod.get_log_level != NULL &&
1197 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_SYSTEM_MEMORY)) {
1198 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,61, "calloc: addr=%p, size=%ld",
1199 ip_service_list[service_number], (unsigned long int) sizeof(struct l7vs_ip_service));
1201 /*------ DEBUG LOG END ------*/
1203 if (ip_service_list[service_number] == NULL) {
1204 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,54, "Could not allocate memory.");
1205 goto create_service_out;
1207 return_value = ip_service_list[service_number];
1208 goto create_service_out;
1212 /* all service list is full */
1213 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,244, "ip service list is full.");
1216 /*-------- DEBUG LOG --------*/
1217 if (ip_protomod.get_log_level != NULL &&
1218 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1219 char ssl_str[DEBUG_STR_LEN] = {0};
1220 l7vs_ip_service_c_str(ssl_str, return_value);
1221 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,280,
1222 "out_function: struct l7vs_ip_service* l7vs_protomod_ip_create_service():"
1223 "return_value=&(%s)", ssl_str);
1225 /*------ DEBUG LOG END ------*/
1227 return return_value;
1231 * Create temporary ip service.
1233 * @return ip service struct when create a service. NULL when cannot create service.
1235 static struct l7vs_ip_service *
1236 l7vs_protomod_ip_create_temp_service()
1238 struct l7vs_ip_service* return_value = NULL;
1240 /*-------- DEBUG LOG --------*/
1241 if (ip_protomod.get_log_level != NULL &&
1242 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1243 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,281,
1244 "in_function: struct l7vs_ip_service* l7vs_protomod_ip_create_temp_service()");
1246 /*------ DEBUG LOG END ------*/
1248 /* if pointer that does not point NULL exists ... */
1249 if (ip_service_list[IP_SERVICE_NUMBER - 1] != NULL) {
1250 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,245, "Temporary ip service is being used by other process.");
1251 goto create_temp_service_out;
1254 /* create temp service */
1255 ip_service_list[IP_SERVICE_NUMBER - 1] = (struct l7vs_ip_service *) calloc(1, sizeof(struct l7vs_ip_service));
1257 /*-------- DEBUG LOG --------*/
1258 if (ip_protomod.get_log_level != NULL &&
1259 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_SYSTEM_MEMORY)) {
1260 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,62, "calloc: addr=%p, size=%ld",
1261 ip_service_list[IP_SERVICE_NUMBER - 1], (unsigned long int) sizeof(struct l7vs_ip_service));
1263 /*------ DEBUG LOG END ------*/
1265 if (ip_service_list[IP_SERVICE_NUMBER - 1] == NULL) {
1266 PUT_LOG_ERROR(ip_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,55, "Could not allocate memory");
1267 goto create_temp_service_out;
1270 return_value = ip_service_list[IP_SERVICE_NUMBER - 1];
1272 create_temp_service_out:
1273 /*-------- DEBUG LOG --------*/
1274 if (ip_protomod.get_log_level != NULL &&
1275 LOG_LV_DEBUG == ip_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1276 char ssl_str[DEBUG_STR_LEN] = {0};
1277 l7vs_ip_service_c_str(ssl_str, return_value);
1278 PUT_LOG_DEBUG(ip_protomod, LOG_CAT_L7VSD_PROTOCOL,282,
1279 "out_function: struct l7vs_ip_service* l7vs_protomod_ip_create_service():"
1280 "return_value=&(%s)", ssl_str);
1282 /*------ DEBUG LOG END ------*/
1284 return return_value;
1288 * Serialize struct l7vs_ip_service for debug log.
1289 * @param[out] buf serialized string
1290 * @param[in] ip l7vs_ip_service struct
1292 static void l7vs_ip_service_c_str(char* buf, struct l7vs_ip_service* ip) {
1294 snprintf(buf, DEBUG_STR_LEN, "NULL");
1297 snprintf(buf, DEBUG_STR_LEN, "service_handle=%d, timeout=%d, forwarded_for=%d, reschedule=%d",
1298 ip->service_handle, ip->timeout, ip->forwarded_for, ip->reschedule);
1303 * Serialize struct l7vs_ip_service_arg for debug log.
1304 * @param[out] buf serialized string
1305 * @param[in] ip_arg l7vs_ip_service_arg struct
1307 void l7vs_ip_service_arg_c_str(char* buf, struct l7vs_ip_service_arg* ip_arg) {
1308 if (ip_arg == NULL) {
1309 snprintf(buf, DEBUG_STR_LEN, "NULL");
1312 snprintf(buf, DEBUG_STR_LEN, "timeout=%d, forwarded_for=%d, reschedule=%d",
1313 ip_arg->timeout, ip_arg->forwarded_for, ip_arg->reschedule);
1317 unsigned int l7vs_ip_service_calc_hash(struct l7vs_conn* conn) {
1318 unsigned int hash = ntohl(conn->caddr.sin_addr.s_addr) * GOLDEN_RATIO_PRIME;
1319 return hash >> 32 - HASH_TABLE_BITS;
1321 // vim:et:ts=4:foldmethod=marker:foldmarker=LOG\ -,LOG\ END\ -: