3 * @brief the framework module of protocol module
4 * @brief it proceeds common function of protocol module
6 * L7VSD: Linux Virtual Server for Layer7 Load Balancing
7 * Copyright (C) 2005 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 **********************************************************************/
27 #include <sys/types.h>
34 #include "l7vs_module.h"
35 #include "l7vs_dest.h"
36 #include "l7vs_service.h"
37 #include "l7vs_sched.h"
38 #include "l7vs_conn.h"
39 #include "l7vs_replication.h"
40 #include "logger_wrapper.h"
42 #if defined(LOGGER_PROCESS_VSD)
43 const LOG_CATEGORY_TAG log_cat_protocol = LOG_CAT_L7VSD_PROTOCOL;
45 const LOG_CATEGORY_TAG log_cat_protocol = LOG_CAT_L7VSADM_PROTOCOL;
48 static struct l7vs_protomod *l7vs_protomod_load(char *modname);
49 static void l7vs_protomod_unload(struct l7vs_protomod *pmod);
50 static gint l7vs_protomod_cmp(struct l7vs_protomod *pmod, char *name);
52 static int protomod_initialize(struct l7vs_service *srv, struct l7vs_conn *conn ,char *buf ,size_t len , struct l7vs_dest **dest);
53 static int protomod_finalize(struct l7vs_service *srv, struct l7vs_conn *conn ,char *buf , size_t len , struct l7vs_dest **dest, int resched);
55 static GList *l7vs_protomod_list = NULL;
57 typedef std::map<LOG_CATEGORY_TAG,LOG_CATEGORY_TAG> log_category_map;
59 log_category_map module_logcategory_map;
60 static enum LOG_LEVEL_TAG protomod_getloglevel( const enum LOG_CATEGORY_TAG );
61 static void protomod_log_debug( const enum LOG_CATEGORY_TAG,
66 static void protomod_log_info( const enum LOG_CATEGORY_TAG,
71 static void protomod_log_warn( const enum LOG_CATEGORY_TAG,
76 static void protomod_log_error( const enum LOG_CATEGORY_TAG,
81 static void protomod_log_fatal( const enum LOG_CATEGORY_TAG,
88 * Protocol module get function.
89 * @param name [in] Protocol module name.
90 * @return Got protocol module.
92 struct l7vs_protomod *
93 l7vs_protomod_get(char *name)
95 struct l7vs_protomod *pmod = NULL;
97 /*-------- DEBUG LOG --------*/
98 if( LOG_LV_DEBUG == logger_get_log_level( log_cat_protocol ) ){
99 LOGGER_PUT_LOG_DEBUG(log_cat_protocol,1,
100 "in_function: struct l7vs_protomod* l7vs_protomod_get(char* name): name=\"%s\"", name);
102 /*------ DEBUG LOG END ------*/
106 LOGGER_PUT_LOG_ERROR(log_cat_protocol,2,
107 "Arg(name) is NULL pointer.");
111 /* lookup from loaded module list */
112 pmod = l7vs_protomod_lookup(name);
115 pmod = l7vs_protomod_load(name);
117 LOGGER_PUT_LOG_ERROR(log_cat_protocol,3,
118 "Protocol module not found (maybe module problem)");
127 /*-------- DEBUG LOG --------*/
128 if( LOG_LV_DEBUG == logger_get_log_level( log_cat_protocol ) ){
129 LOGGER_PUT_LOG_DEBUG(log_cat_protocol,2,
130 "out_function: struct l7vs_protomod* l7vs_protomod_get(char* name): return_value=%p", pmod);
132 /*------ DEBUG LOG END ------*/
138 * Protocol module put function.
139 * @param pmod [in] Protocol module.
142 l7vs_protomod_put(struct l7vs_protomod *pmod)
144 /*-------- DEBUG LOG --------*/
145 if( LOG_LV_DEBUG == logger_get_log_level( log_cat_protocol ) ){
146 LOGGER_PUT_LOG_DEBUG(log_cat_protocol,3,
147 "in_function: void l7vs_protomod_put(struct l7vs_protomod* pmod): pmod=%p", pmod);
149 /*------ DEBUG LOG END ------*/
153 LOGGER_PUT_LOG_ERROR(log_cat_protocol,4,
154 "Arg(pmod) is NULL pointer.");
158 if (--pmod->refcnt <= 0) {
159 l7vs_module_remove(&l7vs_protomod_list, pmod);
160 l7vs_protomod_unload(pmod);
164 /*-------- DEBUG LOG --------*/
165 if( LOG_LV_DEBUG == logger_get_log_level( log_cat_protocol ) ){
166 LOGGER_PUT_LOG_DEBUG(log_cat_protocol,4,
167 "out_function: void l7vs_protomod_put(struct l7vs_protomod* pmod)");
169 /*------ DEBUG LOG END ------*/
174 * Protocol module load function.
175 * @param modname [in] Protocol module name.
176 * @retern Loaded protocol module struct.
178 static struct l7vs_protomod *
179 l7vs_protomod_load(char *modname)
181 struct l7vs_protomod *pmod = NULL;
183 #if defined(LOGGER_PROCESS_ADM)
184 if( module_logcategory_map.empty() ){//make category convert table
185 module_logcategory_map[LOG_CAT_L7VSD_PROTOCOL] = LOG_CAT_L7VSADM_PROTOCOL;
186 module_logcategory_map[LOG_CAT_L7VSD_SYSTEM_MEMORY] = LOG_CAT_L7VSADM_COMMON;
189 if( module_logcategory_map.empty() ){
190 module_logcategory_map[LOG_CAT_L7VSD_PROTOCOL] =LOG_CAT_L7VSD_PROTOCOL;
191 module_logcategory_map[LOG_CAT_L7VSD_SYSTEM_MEMORY] =LOG_CAT_L7VSD_SYSTEM_MEMORY;
194 /*-------- DEBUG LOG --------*/
195 if( LOG_LV_DEBUG == logger_get_log_level( log_cat_protocol ) ){
196 LOGGER_PUT_LOG_DEBUG( log_cat_protocol,5,
197 "in_function: struct l7vs_protomod* l7vs_protomod_load(char* modname): modname=\"%s\"", modname);
199 /*------ DEBUG LOG END ------*/
202 if (modname == NULL) {
203 LOGGER_PUT_LOG_ERROR(log_cat_protocol,5,
204 "Arg(modname) is NULL pointer.");
208 pmod = (struct l7vs_protomod *)l7vs_module_load(modname, "protomod");
211 LOGGER_PUT_LOG_ERROR(log_cat_protocol,6,
212 "Module load error.");
215 pmod->initialize = protomod_initialize;
216 pmod->finalize = protomod_finalize;
219 pmod->get_log_level = logger_get_log_level;
220 pmod->put_log_debug = logger_put_log_debug;
221 pmod->put_log_info = logger_put_log_info;
222 pmod->put_log_warn = logger_put_log_warn;
223 pmod->put_log_error = logger_put_log_error;
224 pmod->put_log_debug = logger_put_log_debug;
226 pmod->get_log_level = protomod_getloglevel;
227 pmod->put_log_debug = protomod_log_debug;
228 pmod->put_log_info = protomod_log_info;
229 pmod->put_log_warn = protomod_log_warn;
230 pmod->put_log_error = protomod_log_error;
231 pmod->put_log_fatal = protomod_log_fatal;
233 #ifndef LOGGER_PROCESS_ADM
234 pmod->replication_pay_memory = l7vs_replication_pay_memory;
237 l7vs_module_register(&l7vs_protomod_list, pmod);
240 /*-------- DEBUG LOG --------*/
241 if( LOG_LV_DEBUG == logger_get_log_level( log_cat_protocol ) ){
242 LOGGER_PUT_LOG_DEBUG(log_cat_protocol,6,
243 "out_function: struct l7vs_protomod* l7vs_protomod_load(char* modname): return_value=%p", pmod);
245 /*------ DEBUG LOG END ------*/
251 * Protocol module unload function.
252 * @param pmod [in] Protocol module.
255 l7vs_protomod_unload(struct l7vs_protomod *pmod)
259 /*-------- DEBUG LOG --------*/
260 if( LOG_LV_DEBUG == logger_get_log_level( log_cat_protocol ) ){
261 LOGGER_PUT_LOG_DEBUG(log_cat_protocol,7,
262 "in_function: void l7vs_protomod_unload(struct l7vs_protomod* pmod): pmod=%p", pmod);
264 /*------ DEBUG LOG END ------*/
268 LOGGER_PUT_LOG_ERROR(log_cat_protocol,7,
269 "Arg(pmod) is NULL pointer.");
274 if (pmod->fini != NULL) {
277 l7vs_module_unload(h);
280 /*-------- DEBUG LOG --------*/
281 if( LOG_LV_DEBUG == logger_get_log_level( log_cat_protocol ) ){
282 LOGGER_PUT_LOG_DEBUG(log_cat_protocol,8,
283 "out_function: void l7vs_protomod_unload(struct l7vs_protomod* pmod)");
285 /*------ DEBUG LOG END ------*/
289 * Protocol module lookup function.
290 * @param modname [in] Protocol module name.
291 * @retern Found protocol module struct.
293 struct l7vs_protomod *
294 l7vs_protomod_lookup(char *modname)
296 struct l7vs_protomod* pmod = NULL;
298 /*-------- DEBUG LOG --------*/
299 if( LOG_LV_DEBUG == logger_get_log_level( log_cat_protocol ) ){
300 LOGGER_PUT_LOG_DEBUG(log_cat_protocol,9,
301 "in_function: struct l7vs_protomod* l7vs_protomod_lookup(char* modname): "
302 "modname=\"%s\"", modname);
304 /*------ DEBUG LOG END ------*/
307 if (modname == NULL) {
308 LOGGER_PUT_LOG_ERROR(log_cat_protocol,8,
309 "Arg(modname) is NULL pointer.");
313 pmod = (struct l7vs_protomod *) l7vs_module_lookup(l7vs_protomod_list, modname,
314 (GCompareFunc) l7vs_protomod_cmp);
317 /*-------- DEBUG LOG --------*/
318 if( LOG_LV_DEBUG == logger_get_log_level( log_cat_protocol ) ){
319 LOGGER_PUT_LOG_DEBUG(log_cat_protocol,10,
320 "out_function: struct l7vs_protomod* l7vs_protomod_load(char* modname): "
321 "return_value=%p", pmod);
323 /*------ DEBUG LOG END ------*/
329 * Protocol module name compare function.
330 * @param pmod [in] Protocol module.
331 * @param name [in] Protocol module name.
333 * @retval <0, >0 Not match.
336 l7vs_protomod_cmp(struct l7vs_protomod *pmod, char *name)
340 /*-------- DEBUG LOG --------*/
341 if( LOG_LV_DEBUG == logger_get_log_level( log_cat_protocol ) ){
342 LOGGER_PUT_LOG_DEBUG(log_cat_protocol,11,
343 "in_function: gint l7vs_protomod_cmp(struct l7vs_protomod* pmod, char* name): "
344 "pmod=%p, name=\"%s\"", pmod, name);
346 /*------ DEBUG LOG END ------*/
350 LOGGER_PUT_LOG_ERROR(log_cat_protocol,9,
351 "Arg(pmod) is NULL pointer.");
356 LOGGER_PUT_LOG_ERROR(log_cat_protocol,10,
357 "Arg(name) is NULL pointer.");
362 return_value = strcmp(pmod->modname, name);
365 /*-------- DEBUG LOG --------*/
366 if( LOG_LV_DEBUG == logger_get_log_level( log_cat_protocol ) ){
367 LOGGER_PUT_LOG_DEBUG(log_cat_protocol,12,
368 "out_function: gint l7vs_protomod_cmp(struct l7vs_protomod* pmod, char* name): "
369 "return_value=%d", return_value);
371 /*------ DEBUG LOG END ------*/
377 * Protocol module initialize function.
378 * @param srv [in] Virtual service struct.
379 * @param conn [in] Client connection struct.
380 * @param buf [in] Client request payload.
381 * @param len [in] Length of client request payload.
382 * @param dest [out] Destination struct list.
387 protomod_initialize(struct l7vs_service *srv, struct l7vs_conn *conn, char *buf, size_t len, struct l7vs_dest **dest)
389 int return_value = 0;
391 /*-------- DEBUG LOG --------*/
392 if( LOG_LV_DEBUG == logger_get_log_level( log_cat_protocol ) ){
393 char srv_str[DEBUG_STR_LEN] = {0};
394 char conn_str[DEBUG_STR_LEN] = {0};
395 char dest_str[DEBUG_STR_LEN] = {0};
396 l7vs_service_c_str(srv_str, srv);
397 l7vs_conn_c_str(conn_str, conn);
399 strncpy(dest_str, "NULL", DEBUG_STR_LEN);
402 l7vs_dest_c_str(dest_str, *dest);
404 LOGGER_PUT_LOG_DEBUG(log_cat_protocol,13,
405 "in_function: int protomod_initialize(struct l7vs_service* srv, struct l7vs_conn* conn, "
406 "char* buf, size_t len, struct l7vs_dest** dest): srv=&(%s), conn=&(%s), buf=\"%s\", "
407 "len=%ld, dest=&(&(%s))", srv_str, conn_str, buf, (long int)len, dest_str);
409 /*------ DEBUG LOG END ------*/
413 LOGGER_PUT_LOG_ERROR(log_cat_protocol,11,
414 "Arg(dest) is NULL pointer.");
419 /* clean up destination list */
423 /*-------- DEBUG LOG --------*/
424 if( LOG_LV_DEBUG == logger_get_log_level( log_cat_protocol ) ){
425 LOGGER_PUT_LOG_DEBUG(log_cat_protocol,14,
426 "out_function: int protomod_initialize(struct l7vs_service* srv, struct l7vs_conn* conn, "
427 "char* buf, size_t len, struct l7vs_dest** dest): return_value=%d", return_value);
429 /*------ DEBUG LOG END ------*/
435 * Protocol module finalize function.
436 * @param srv [in] Virtual service struct.
437 * @param conn [in] Client connection struct.
438 * @param buf [in] Client request payload.
439 * @param len [in] Length of client request payload.
440 * @param dest [out] Destination struct list.
445 protomod_finalize(struct l7vs_service *srv, struct l7vs_conn *conn, char *buf, size_t len, struct l7vs_dest **dest, int resched)
449 GList *active_dest = NULL;
450 int return_value = 0;
452 /*-------- DEBUG LOG --------*/
453 if( LOG_LV_DEBUG == logger_get_log_level( log_cat_protocol ) ){
454 char srv_str[DEBUG_STR_LEN] = {0};
455 char conn_str[DEBUG_STR_LEN] = {0};
456 char dest_str[DEBUG_STR_LEN] = {0};
457 l7vs_service_c_str(srv_str, srv);
458 l7vs_conn_c_str(conn_str, conn);
460 strncpy(dest_str, "NULL", DEBUG_STR_LEN);
463 l7vs_dest_c_str(dest_str, *dest);
465 LOGGER_PUT_LOG_DEBUG(log_cat_protocol,15,
466 "in_function: int protomod_finalize(struct l7vs_service* srv, struct l7vs_conn* conn, "
467 "char* buf, size_t len, struct l7vs_dest** dest, int resched): srv=&(%s), conn=&(%s), buf=\"%s\", "
468 "len=%ld, dest=&(&(%s)), resched=%d", srv_str, conn_str, buf, (long int)len, dest_str, resched);
470 /*------ DEBUG LOG END ------*/
474 LOGGER_PUT_LOG_ERROR(log_cat_protocol,12,
475 "Arg(srv) is NULL pointer.");
480 LOGGER_PUT_LOG_ERROR(log_cat_protocol,13,
481 "Arg(dest) is NULL pointer.");
486 // pick up active real server (weight > 0)
487 for (l = g_list_first(srv->dest_list); l != NULL; l = g_list_next(l)) {
488 d = (struct l7vs_dest*) l->data;
490 active_dest = g_list_append(active_dest, l->data);
494 if((*dest) != NULL ){
495 // check dest whether it exists in active real server list
496 for( l = g_list_first(active_dest); l != NULL; l = g_list_next(l) ){
497 d = (struct l7vs_dest*) l->data;
498 if((d->addr.sin_addr.s_addr == (*dest)->addr.sin_addr.s_addr ) &&
499 (d->addr.sin_port == (*dest)->addr.sin_port) ){
507 LOGGER_PUT_LOG_INFO(log_cat_protocol,1, "RealServer nonexistence.");
513 *dest = srv->scheduler->schedule(srv, conn);
516 LOGGER_PUT_LOG_INFO(log_cat_protocol,2, "RealServer nonexistence.");
523 *dest = srv->scheduler->schedule(srv, conn);
526 LOGGER_PUT_LOG_INFO(log_cat_protocol,3, "RealServer nonexistence.");
533 g_list_free(active_dest);
535 /*-------- DEBUG LOG --------*/
536 if( LOG_LV_DEBUG == logger_get_log_level( log_cat_protocol ) ){
537 LOGGER_PUT_LOG_DEBUG(log_cat_protocol,16,
538 "out_function: int protomod_finalize(struct l7vs_service* srv, struct l7vs_conn* conn, "
539 "char* buf, size_t len, struct l7vs_dest** dest, int resched): return_value=%d", return_value);
541 /*------ DEBUG LOG END ------*/
548 * log getter local function
551 static enum LOG_LEVEL_TAG protomod_getloglevel( const enum LOG_CATEGORY_TAG cat ){
552 log_category_map::iterator itr = module_logcategory_map.find( cat );
553 if( itr != module_logcategory_map.end() ){
554 return logger_get_log_level( itr->second );
557 itr = module_logcategory_map.begin();
558 return logger_get_log_level( itr->second );
562 static void protomod_log_debug( const enum LOG_CATEGORY_TAG cat,
563 const unsigned int message_id,
566 const char* message ){
567 log_category_map::iterator itr = module_logcategory_map.find( cat );
568 if( itr == module_logcategory_map.end() )
569 itr = module_logcategory_map.begin();
570 logger_put_log_debug( itr->second, message_id, file, line, message );
573 static void protomod_log_info( const enum LOG_CATEGORY_TAG cat,
574 const unsigned int message_id,
577 const char* message ){
578 log_category_map::iterator itr = module_logcategory_map.find( cat );
579 if( itr == module_logcategory_map.end() )
580 itr = module_logcategory_map.begin();
581 logger_put_log_info( itr->second, message_id, file, line, message );
584 static void protomod_log_warn( const enum LOG_CATEGORY_TAG cat,
585 const unsigned int message_id,
588 const char* message ){
589 log_category_map::iterator itr = module_logcategory_map.find( cat );
590 if( itr == module_logcategory_map.end() )
591 itr = module_logcategory_map.begin();
592 logger_put_log_warn( itr->second, message_id, file, line, message );
595 static void protomod_log_error( const enum LOG_CATEGORY_TAG cat,
596 const unsigned int message_id,
599 const char* message ){
600 log_category_map::iterator itr = module_logcategory_map.find( cat );
601 if( itr == module_logcategory_map.end() )
602 itr = module_logcategory_map.begin();
603 logger_put_log_error( itr->second, message_id, file, line, message );
606 static void protomod_log_fatal( const enum LOG_CATEGORY_TAG cat,
607 const unsigned int message_id,
610 const char* message ){
611 log_category_map::iterator itr = module_logcategory_map.find( cat );
612 if( itr == module_logcategory_map.end() )
613 itr = module_logcategory_map.begin();
614 logger_put_log_fatal( itr->second, message_id, file, line, message );