2 * @file protomod_sslid.c
3 * @brief protocol module of HTTPS(SSL/TLS).
4 * @brief this module provide session persistence by SSL session ID.
6 * L7VSD: Linux Virtual Server for Layer7 Load Balancing
7 * Copyright (C) 2008 NTT COMWARE Corporation.
8 * Copyright (C) 2009 Shinya TAKEBAYASHI
9 * Copyright (C) 2009 NTT Resonant Inc. O.Nakayama, T.Motoda.
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 **********************************************************************/
28 #define __STDC_LIMIT_MACROS
35 #include "l7vs_service.h"
36 #include "l7vs_conn.h"
37 #include "l7vs_lsock.h"
38 #include "l7vs_dest.h"
39 #include "l7vs_replication.h"
40 #include "l7vs_module.h"
41 #include "module_http.h"
42 #include "module_sslid_hash.h"
43 #include "protomod_sslid.h"
45 static void fini(void);
46 static int create(void*, handle_t);
47 static void* create_sa(struct l7vs_service_arg*);
48 static int compare(handle_t, handle_t);
49 static int select_dest(struct l7vs_service*, struct l7vs_conn*,
50 char*, size_t*, struct l7vs_dest**);
51 static int analyze_cldata(struct l7vs_service*, struct l7vs_conn*,
53 static int analyze_rsdata(struct l7vs_service*, struct l7vs_conn*,
55 static int destroy(handle_t);
56 static void destroy_sa(void**);
57 static int service_arg(struct l7vs_service_arg_multi*, handle_t);
58 static int parse(void*, int, char**);
60 static struct l7vs_sslid_service* l7vs_protomod_sslid_search_service(handle_t);
61 static struct l7vs_sslid_service* l7vs_protomod_sslid_create_service();
62 static struct l7vs_sslid_service* l7vs_protomod_sslid_create_temp_service();
64 static void l7vs_protomod_sslid_read_replication_data(struct l7vs_sslid_service*, struct l7vs_service*);
65 static void l7vs_protomod_sslid_write_replication_data(struct l7vs_sslid_service*);
67 static void l7vs_sslid_service_c_str(char*, struct l7vs_sslid_service*);
68 static void l7vs_sslid_service_arg_c_str(char*, struct l7vs_sslid_service_arg*);
69 static void ssl_session_c_str(char*, struct ssl_session*);
70 static void replication_header_c_str(char*, struct replication_header*);
71 static void id_c_str(char*, char*, int); /* add session id length param 2009.4.8 T.Motoda@NTTR */
73 struct l7vs_sslid_service* sslid_service_list[SSLID_SERVICE_NUMBER];
75 static struct l7vs_protomod sslid_protomod = {
77 "sslid", /* modname */
79 0, /* fast schedule */
80 create, /* create function */
81 compare, /* compare function */
82 select_dest, /* select_dest function */
83 analyze_cldata, /* analyze_cldata function */
84 analyze_rsdata, /* analyze_rsdata function */
85 destroy, /* destroy function */
86 fini, /* fini function */
87 create_sa, /* create_sa function */
88 service_arg, /* service_arg function */
89 parse, /* parse function */
90 destroy_sa, /* destroy_sa function */
91 NULL, /* initialize function */
92 NULL, /* finalize function */
93 NULL, /* get_log_level function */
94 NULL, /* put_log_debug function */
95 NULL, /* put_log_info function */
96 NULL, /* put_log_warn function */
97 NULL, /* put_log_error function */
98 NULL, /* put_log_fatal function */
99 NULL /* replication_pay_memory function */
103 * Protocol module initialize function. This function run when dlopen and dlsym at first time.
104 * @param[in] handle dlopen's handle
105 * @return l7vs_protomod struct
107 extern "C" struct l7vs_protomod*
110 struct l7vs_protomod* return_value = NULL;
112 /*-------- DEBUG LOG --------*/
113 if (sslid_protomod.get_log_level != NULL &&
114 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
115 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,92,
116 "in_function: struct l7vs_protomod* init(void* handle): handle=%p", handle);
118 /*------ DEBUG LOG END ------*/
121 if (handle == NULL) {
122 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,79, "Arg(handle) is NULL pointer.");
126 /* initialize sslid service list */
127 memset(sslid_service_list, 0, sizeof(struct l7vs_sslid_service*) * SSLID_SERVICE_NUMBER);
128 /* set dlopen's handle */
129 sslid_protomod.handle = handle;
131 return_value = &sslid_protomod;
134 /*-------- DEBUG LOG --------*/
135 if (sslid_protomod.get_log_level != NULL &&
136 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
137 char protomod_str[DEBUG_STR_LEN] = {0};
138 l7vs_protomod_c_str(protomod_str, &sslid_protomod);
139 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,93,
140 "out_function: struct l7vs_protomod* init(void* handle): return=&(%s)", protomod_str);
142 /*------ DEBUG LOG END ------*/
147 * Protocol module finalize function. free all sslid service list just in case.
154 /* sslid service list counter */
155 int service_number = 0;
157 /*-------- DEBUG LOG --------*/
158 if (sslid_protomod.get_log_level != NULL &&
159 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
160 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,94, "in_function: void fini(void)");
162 /*------ DEBUG LOG END ------*/
164 /* check all sslid service list */
165 for (service_number = 0; service_number < SSLID_SERVICE_NUMBER; ++service_number) {
166 /* if pointer that does not point NULL exists ... */
167 if (sslid_service_list[service_number] != NULL) {
168 /* free and points NULL */
169 if (sslid_service_list[service_number]->session != NULL) {
171 /*-------- DEBUG LOG --------*/
172 if (sslid_protomod.get_log_level != NULL &&
173 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_SYSTEM_MEMORY)) {
174 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,25, "free: %p",
175 sslid_service_list[service_number]->session);
177 /*------ DEBUG LOG END ------*/
179 free(sslid_service_list[service_number]->session);
180 sslid_service_list[service_number]->session = NULL;
181 hash_setPointer(sslid_service_list[service_number]->hash_map, sslid_service_list[service_number]->hash_list, sslid_service_list[service_number]->maxlist);
185 /*-------- DEBUG LOG --------*/
186 if (sslid_protomod.get_log_level != NULL &&
187 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_SYSTEM_MEMORY)) {
188 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,26, "free: %p",
189 sslid_service_list[service_number]);
191 /*------ DEBUG LOG END ------*/
193 free(sslid_service_list[service_number]);
194 sslid_service_list[service_number] = NULL;
198 /*-------- DEBUG LOG --------*/
199 if (sslid_protomod.get_log_level != NULL &&
200 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
201 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,95, "out_function: void fini(void)");
203 /*------ DEBUG LOG END ------*/
207 * Create sslid service struct.
208 * @param[in] sslid_arg sslid service argument struct
209 * @param[in] service_handle a unique service ID
210 * @retval 0 successfully create sslid service.
211 * @retval -1 some errors occur.
214 create(void* sslid_arg, handle_t service_handle)
216 struct l7vs_sslid_service* sslid_service;
217 struct l7vs_sslid_service_arg* sslid_service_arg;
218 int return_value = 0;
220 /*-------- DEBUG LOG --------*/
221 if (sslid_protomod.get_log_level != NULL &&
222 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
223 char sslid_arg_str[DEBUG_STR_LEN] = {0};
224 l7vs_sslid_service_arg_c_str(sslid_arg_str, (struct l7vs_sslid_service_arg*) sslid_arg);
225 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,96,
226 "in_function: int create(void* sslid_arg, handle_t service_handle):sslid_arg=&(%s), "
227 "service_handle=%d", sslid_arg_str, service_handle);
229 /*------ DEBUG LOG END ------*/
232 if (sslid_arg == NULL) {
233 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,80, "Arg(sslid_arg) is NULL pointer.");
238 if (service_handle != TEMP_SERVICEHANDLE) {
239 /* search empty sslid service list and create sslid service */
240 sslid_service = l7vs_protomod_sslid_create_service();
243 /* create temporary sslid service */
244 sslid_service = l7vs_protomod_sslid_create_temp_service();
247 /*-------- DEBUG LOG --------*/
248 if (sslid_protomod.get_log_level != NULL &&
249 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
250 char sslid_str[DEBUG_STR_LEN] = {0};
251 l7vs_sslid_service_c_str(sslid_str, sslid_service);
252 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,97, "pointer assign: sslid_service=&(%s)",
255 /*------ DEBUG LOG END ------*/
257 if (sslid_service == NULL) {
258 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,81, "Could not make sslid service.");
263 sslid_service_arg = (struct l7vs_sslid_service_arg*) sslid_arg;
265 /* set service handle */
266 sslid_service->service_handle = service_handle;
268 /* set option value */
269 sslid_service->timeout = sslid_service_arg->timeout;
270 sslid_service->maxlist = sslid_service_arg->maxlist;
271 sslid_service->replication_addr = NULL;
272 sslid_service->reschedule = sslid_service_arg->reschedule;
274 if (service_handle != TEMP_SERVICEHANDLE) {
275 /* create session area */
276 sslid_service->session = (struct ssl_session*) calloc(sizeof(struct ssl_session), sslid_service->maxlist);
277 hash_allocate(sslid_service_arg->maxlist);
278 sslid_service->hash_map = hash_getIDMAP();
279 sslid_service->hash_list = hash_getIDLIST();
281 /*-------- DEBUG LOG --------*/
282 if (sslid_protomod.get_log_level != NULL &&
283 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_SYSTEM_MEMORY)) {
284 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,27, "calloc: addr=%p, size=%ld",
285 sslid_service->session, (unsigned long int) sizeof(struct ssl_session) * sslid_service->maxlist);
287 /*------ DEBUG LOG END ------*/
289 if (sslid_service->session == NULL) {
290 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,22, "Could not allocate memory.");
291 if (destroy(service_handle)) {
292 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,23,
293 "Could not destroy SSL service. (handle=%d)", service_handle);
301 /*-------- DEBUG LOG --------*/
302 if (sslid_protomod.get_log_level != NULL &&
303 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
304 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,98,
305 "out_function: int create(void* sslid_arg, handle_t service_handle):return_value=%d",
308 /*------ DEBUG LOG END ------*/
314 * Create sslid service argument struct.
315 * @param[out] srv_arg service argument struct
316 * @return sslid service argument struct
319 create_sa(struct l7vs_service_arg* srv_arg)
321 struct l7vs_sslid_service_arg* sslid_service_arg;
323 /*-------- DEBUG LOG --------*/
324 if (sslid_protomod.get_log_level != NULL &&
325 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
326 char service_arg_str[DEBUG_STR_LEN] = {0};
327 l7vs_service_arg_c_str(service_arg_str, srv_arg);
328 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,99,
329 "in_function: void* create_sa(struct l7vs_service_arg* srv_arg):srv_arg=&(%s)",
332 /*------ DEBUG LOG END ------*/
335 if (srv_arg == NULL) {
336 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,82, "Arg(srv_arg) is NULL pointer.");
337 sslid_service_arg = NULL;
341 /* create sslid service argument struct */
342 sslid_service_arg = (struct l7vs_sslid_service_arg*) calloc(1, sizeof(struct l7vs_sslid_service_arg));
344 /*-------- DEBUG LOG --------*/
345 if (sslid_protomod.get_log_level != NULL &&
346 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_SYSTEM_MEMORY)) {
347 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,28, "calloc: addr=%p, size=%ld",
348 sslid_service_arg, (unsigned long int) sizeof(struct l7vs_sslid_service_arg));
350 /*------ DEBUG LOG END ------*/
352 if (sslid_service_arg == NULL) {
353 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,24, "Could not allocate memory.");
357 /* set sslid service argument size and protomod name "sslid" */
358 srv_arg->len = sizeof(struct l7vs_sslid_service_arg);
359 strcpy(srv_arg->protomod, sslid_protomod.modname);
362 /*-------- DEBUG LOG --------*/
363 if (sslid_protomod.get_log_level != NULL &&
364 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
365 char sslid_service_arg_str[DEBUG_STR_LEN] = {0};
366 l7vs_sslid_service_arg_c_str(sslid_service_arg_str, sslid_service_arg);
367 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,100,
368 "out_function: void* create_sa(struct l7vs_service_arg* srv_arg):return_value=&(%s)",
369 sslid_service_arg_str);
371 /*------ DEBUG LOG END ------*/
373 return (void*) sslid_service_arg;
377 * Always match 'cause SSL-Session-ID module does not have module key.
378 * @param[in] srv_handle1 one of a unique service ID
379 * @param[in] srv_handle2 one of a unique service ID
380 * @retval 0 they matched perfectly.
381 * @retval -1 they are different.
384 compare(handle_t srv_handle1, handle_t srv_handle2)
386 int return_value = 0;
388 /*-------- DEBUG LOG --------*/
389 if (sslid_protomod.get_log_level != NULL &&
390 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
391 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,101,
392 "in_function: int compare(handle_t srv_handle1, handle_t srv_handle2):"
393 "srv_handle1=%u, srv_handle2=%u", srv_handle1, srv_handle2);
395 /*------ DEBUG LOG END ------*/
397 /*-------- DEBUG LOG --------*/
398 if (sslid_protomod.get_log_level != NULL &&
399 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
400 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,102,
401 "out_function: int compare(handle_t srv_handle1, handle_t srv_handle2):return_value=%d",
404 /*------ DEBUG LOG END ------*/
410 * Check and modify request packet.
411 * @param[in] srv service struct include service handle, protocol module and schedule module.
412 * @param[in] conn connection data.
413 * @param[in] request packet data from client
414 * @param[in] len length of packet data
415 * @param[out] dest destination (real server) list
416 * @param[out] tcps TCP Splicer flag
417 * @retval 0 successfully check packet data
418 * @retval -1 some errors occur.
421 select_dest(struct l7vs_service* srv, struct l7vs_conn* conn,
422 char* request, size_t* len, struct l7vs_dest** dest)
424 struct l7vs_sslid_service* sslid_service;
427 int return_value = 0;
429 char id_str[DEBUG_STR_LEN] = {0};
430 struct l7vs_dest *tmpdest = NULL;
433 /*-------- DEBUG LOG --------*/
434 if (sslid_protomod.get_log_level != NULL &&
435 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
436 char srv_str[DEBUG_STR_LEN] = {0};
437 char conn_str[DEBUG_STR_LEN] = {0};
438 char dest_str[DEBUG_STR_LEN] = {0};
439 char len_str[DEBUG_STR_LEN] = {0};
440 l7vs_service_c_str(srv_str, srv);
441 l7vs_conn_c_str(conn_str, conn);
443 l7vs_dest_c_str(dest_str, *dest);
446 strncpy(dest_str, "NULL", DEBUG_STR_LEN);
449 snprintf(len_str, DEBUG_STR_LEN, "%lu", (unsigned long int) *len);
452 strncpy(len_str, "NULL", DEBUG_STR_LEN);
454 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,103,
455 "in_function: int select_dest(struct l7vs_service* srv, struct l7vs_conn* conn, "
456 "char* request, size_t* len, struct l7vs_dest** dest):srv=&(%s), conn=&(%s), "
457 "request=\"%s\", len=&(%s), dest=&(&(%s))",
458 srv_str, conn_str, request, len_str, dest_str);
460 /*------ DEBUG LOG END ------*/
464 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,83, "Arg(srv) is NULL pointer.");
466 goto select_dest_out;
468 if (srv->pm == NULL) {
469 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,84, "Arg(srv->pm) is NULL pointer.");
471 goto select_dest_out;
473 if (request == NULL) {
474 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,85, "Arg(request) is NULL pointer.");
476 goto select_dest_out;
479 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,86, "Arg(len) is NULL pointer.");
481 goto select_dest_out;
484 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,87, "Arg(dest) is NULL pointer.");
486 goto select_dest_out;
489 /* search service that has such a service ID */
490 sslid_service = l7vs_protomod_sslid_search_service(srv->handle);
492 /*-------- DEBUG LOG --------*/
493 if (sslid_protomod.get_log_level != NULL &&
494 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
495 char sslid_str[DEBUG_STR_LEN] = {0};
496 l7vs_sslid_service_c_str(sslid_str, sslid_service);
497 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,104, "pointer assign: sslid_service=&(%s)",
500 /*------ DEBUG LOG END ------*/
502 if (sslid_service == NULL) {
503 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,89, "Could not find such service handle's sslid service.");
505 goto select_dest_out;
507 if (sslid_service->session == NULL) {
508 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,90,
509 "Service has NULL pointer session.");
511 goto select_dest_out;
514 /* read replication data */
515 if (sslid_service->replication_addr) {
516 l7vs_protomod_sslid_read_replication_data(sslid_service, srv);
517 hash_rebuild_sessionlist(sslid_service);
520 /* initialize protocol module ... clear destination list */
521 ret = srv->pm->initialize(srv, conn, request, *len, dest);
523 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,91, "Could not initialize protomod.");
525 goto select_dest_out;
530 *len > 44 && // Check if minimum length 2009.4.8 O.Nakayama@NTTR and T.Motoda@NTTR
532 (request[1] == 0x03 && request[2] == 0x00 && request[9] == 0x03 && request [10] == 0x00) || // SSL v3
533 (request[1] == 0x03 && request[2] == 0x01 && request[9] == 0x03 && request [10] == 0x01) // TLS v1
535 request[5] == 0x01 && // Client Hello
536 (request[43] >= 1 && request[43] <= SSLID_LENGTH && *len > (43 + request[43])) // Session ID Length (variable length from 1 to SSLID_LENGTH) 2009.4.8 O.Nakayama and T.Motoda@NTTR
538 /*-------- DEBUG LOG --------*/
539 if (sslid_protomod.get_log_level != NULL &&
540 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
541 char id_str[DEBUG_STR_LEN] = {0};
542 id_c_str(id_str, &request[44], request[43]); // Add length parameter 2009.4.8 T.Motoda@NTTR
543 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,105,
544 "Client Hello/SessionID=%s", id_str);
546 /*------ DEBUG LOG END ------*/
548 hash_setPointer(sslid_service->hash_map, sslid_service->hash_list, sslid_service->maxlist);
549 id_c_str(id_str, &request[44], request[43]); // Add length parameter 2009.4.8 T.Motoda@NTTR
550 searchret = hash_search(id_str, &tmpdest);
552 if (searchret == 0) {
559 ret = srv->pm->finalize(srv, conn, request, *len, dest, sslid_service->reschedule);
561 PUT_LOG_INFO(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,11, "Could not finalize protomod. (Realserver decision failure)");
563 goto select_dest_out;
567 /*-------- DEBUG LOG --------*/
568 if (sslid_protomod.get_log_level != NULL &&
569 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
570 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,107,
571 "out_function: int select_dest(struct l7vs_service* srv, struct l7vs_conn* conn, "
572 "char* request, size_t* len, struct l7vs_dest** dest, int* tcps):return_value=%d",
575 /*------ DEBUG LOG END ------*/
582 * @param[in] srv service struct include service handle, protocol module and schedule module.
583 * @param[in] conn connection data.
584 * @param[in] request packet data from client
585 * @param[in] len length of packet data
586 * @retval 0 successfully check packet data
587 * @retval -1 some errors occur.
590 analyze_cldata(struct l7vs_service* srv, struct l7vs_conn* conn,
591 char* request, size_t* len)
593 struct l7vs_sslid_service* sslid_service;
594 int return_value = 0;
596 /*-------- DEBUG LOG --------*/
597 if (sslid_protomod.get_log_level != NULL &&
598 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
599 char srv_str[DEBUG_STR_LEN] = {0};
600 char conn_str[DEBUG_STR_LEN] = {0};
601 char dest_str[DEBUG_STR_LEN] = {0};
602 char len_str[DEBUG_STR_LEN] = {0};
603 l7vs_service_c_str(srv_str, srv);
604 l7vs_conn_c_str(conn_str, conn);
606 snprintf(len_str, DEBUG_STR_LEN, "%lu", (unsigned long int) *len);
609 strncpy(len_str, "NULL", DEBUG_STR_LEN);
611 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,325,
612 "in_function: int analyze_cldata(struct l7vs_service* srv, struct l7vs_conn* conn, "
613 "char* request, size_t* len):srv=&(%s), conn=&(%s), "
614 "request=\"%s\", len=&(%s)",
615 srv_str, conn_str, request, len_str);
617 /*------ DEBUG LOG END ------*/
621 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,310, "Arg(srv) is NULL pointer.");
623 goto analyze_cldata_out;
625 if (srv->pm == NULL) {
626 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,311, "Arg(srv->pm) is NULL pointer.");
628 goto analyze_cldata_out;
630 if (request == NULL) {
631 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,312, "Arg(request) is NULL pointer.");
633 goto analyze_cldata_out;
636 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,313, "Arg(len) is NULL pointer.");
638 goto analyze_cldata_out;
641 /* search service that has such a service ID */
642 sslid_service = l7vs_protomod_sslid_search_service(srv->handle);
644 /*-------- DEBUG LOG --------*/
645 if (sslid_protomod.get_log_level != NULL &&
646 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
647 char sslid_str[DEBUG_STR_LEN] = {0};
648 l7vs_sslid_service_c_str(sslid_str, sslid_service);
649 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,326, "pointer assign: sslid_service=&(%s)",
652 /*------ DEBUG LOG END ------*/
654 if (sslid_service == NULL) {
655 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,314, "Could not find such service handle's sslid service.");
657 goto analyze_cldata_out;
659 if (sslid_service->session == NULL) {
660 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,315,
661 "Service has NULL pointer session.");
663 goto analyze_cldata_out;
667 /*-------- DEBUG LOG --------*/
668 if (sslid_protomod.get_log_level != NULL &&
669 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
670 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,327,
671 "out_function: int analyze_cldata(struct l7vs_service* srv, struct l7vs_conn* conn, "
672 "char* request, size_t* len):return_value=%d", return_value);
674 /*------ DEBUG LOG END ------*/
680 * Check and modify response packet.
681 * @param[in] srv service struct include service handle, protocol module and schedule module.
682 * @param[in] conn connection data.
683 * @param[in] response packet data from real server
684 * @param[in] len length of packet data. it will be lengthened.
685 * @retval 0 successfully check packet data.
686 * @retval -1 some errors occur.
689 analyze_rsdata(struct l7vs_service* srv, struct l7vs_conn* conn,
690 char* response, size_t* len)
692 struct l7vs_sslid_service* sslid_service;
694 int return_value = 0;
697 time_t now, oldest = 0;
698 char session_full = 1;
699 char id_str[DEBUG_STR_LEN] = {0};
701 /*-------- DEBUG LOG --------*/
702 if (sslid_protomod.get_log_level != NULL &&
703 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
704 char srv_str[DEBUG_STR_LEN] = {0};
705 char conn_str[DEBUG_STR_LEN] = {0};
706 char len_str[DEBUG_STR_LEN] = {0};
707 l7vs_service_c_str(srv_str, srv);
708 l7vs_conn_c_str(conn_str, conn);
710 snprintf(len_str, DEBUG_STR_LEN, "%lu", (unsigned long int) *len);
713 strncpy(len_str, "NULL", DEBUG_STR_LEN);
715 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,108,
716 "in_function: int analyze_rsdata(struct l7vs_service* srv, struct l7vs_conn* conn, "
717 "char* response, size_t* len):srv=&(%s), conn=&(%s), response=\"%s\", len=&(%s)",
718 srv_str, conn_str, response, len_str);
720 /*------ DEBUG LOG END ------*/
724 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,93, "Arg(srv) is NULL pointer.");
726 goto analyze_rsdata_out;
729 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,94, "Arg(conn) is NULL pointer.");
731 goto analyze_rsdata_out;
733 if (conn->dest == NULL) {
734 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,95, "Arg(conn->dest) is NULL pointer.");
736 goto analyze_rsdata_out;
738 if (response == NULL) {
739 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,96, "Arg(response) is NULL pointer.");
741 goto analyze_rsdata_out;
744 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,97, "Arg(len) is NULL pointer.");
746 goto analyze_rsdata_out;
749 /* sorry flag check */
750 if (conn->sorry_conn_flag == 1) {
751 /*-------- DEBUG LOG --------*/
752 if (sslid_protomod.get_log_level != NULL &&
753 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
754 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,109, "Response from sorry server.");
756 /*------ DEBUG LOG END ------*/
758 goto analyze_rsdata_out;
761 /* search service that has such a service ID */
762 sslid_service = l7vs_protomod_sslid_search_service(srv->handle);
764 /*-------- DEBUG LOG --------*/
765 if (sslid_protomod.get_log_level != NULL &&
766 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
767 char sslid_str[DEBUG_STR_LEN] = {0};
768 l7vs_sslid_service_c_str(sslid_str, sslid_service);
769 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,110, "pointer assign: sslid_service=&(%s)",
772 /*------ DEBUG LOG END ------*/
774 if (sslid_service == NULL) {
775 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,98,
776 "Could not find such service handle's sslid service.");
778 goto analyze_rsdata_out;
780 if (sslid_service->session == NULL) {
781 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,99,
782 "Service has NULL pointer session.");
784 goto analyze_rsdata_out;
789 *len > 44 && // Check if minimum length 2009.4.8 O.Nakayama and T.Motoda@NTTR
791 (response[1] == 0x03 && response[2] == 0x00 && response[9] == 0x03 && response [10] == 0x00) || // SSL v3
792 (response[1] == 0x03 && response[2] == 0x01 && response[9] == 0x03 && response [10] == 0x01) // TLS v1
794 response[5] == 0x02 && // Server Hello
795 (response[43] >= 1 && response[43] <= SSLID_LENGTH && *len > (43 + response[43])) // Session ID Length (variable length from 1 to SSLID_LENGTH) 2009.4.8 O.Nakayama and T.Motoda@NTTR
797 /*-------- DEBUG LOG --------*/
798 if (sslid_protomod.get_log_level != NULL &&
799 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
800 char id_str[DEBUG_STR_LEN] = {0};
801 id_c_str(id_str, &response[44], response[43]); // Add length parameter 2009.4.8 T.Motoda@NTTR
802 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,111,
803 "Server Hello/SessionID=%s", id_str);
805 /*------ DEBUG LOG END ------*/
807 hash_setPointer(sslid_service->hash_map, sslid_service->hash_list, sslid_service->maxlist);
808 id_c_str(id_str, &response[44], response[43]); // Add length parameter 2009.4.8 T.Motoda@NTTR
809 hash_add(id_str, *conn->dest);
810 if (sslid_service->replication_addr) {
811 hash_construct_sessionlist(sslid_service);
812 l7vs_protomod_sslid_write_replication_data(sslid_service);
817 /*-------- DEBUG LOG --------*/
818 if (sslid_protomod.get_log_level != NULL &&
819 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
820 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,114,
821 "out_function: int analyze_rsdata(struct l7vs_service* srv, struct l7vs_conn* conn, "
822 "char* response, size_t* len):return_value=%d", return_value);
824 /*------ DEBUG LOG END ------*/
830 * Destroy sslid service
831 * @param[in] srv_handle a unique service ID
832 * @retval 0 successfully check packet data.
833 * @retval -1 some errors occur.
836 destroy(handle_t srv_handle)
838 /* sslid service list counter */
839 int service_number = 0;
841 int return_value = 0;
843 /*-------- DEBUG LOG --------*/
844 if (sslid_protomod.get_log_level != NULL &&
845 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
846 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,115,
847 "in_function: int destroy(handle_t srv_handle):srv_handle=%u",
850 /*------ DEBUG LOG END ------*/
852 /* check all sslid service list */
853 for (service_number = 0; service_number < SSLID_SERVICE_NUMBER; ++service_number) {
854 /* found sslid service that has srv_handle */
855 if (sslid_service_list[service_number] != NULL &&
856 sslid_service_list[service_number]->service_handle == srv_handle) {
859 if (sslid_service_list[service_number]->session != NULL) {
861 /*-------- DEBUG LOG --------*/
862 if (sslid_protomod.get_log_level != NULL &&
863 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_SYSTEM_MEMORY)) {
864 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,29, "free: %p",
865 sslid_service_list[service_number]->session);
867 /*------ DEBUG LOG END ------*/
869 free(sslid_service_list[service_number]->session);
870 sslid_service_list[service_number]->session = NULL;
871 hash_setPointer(sslid_service_list[service_number]->hash_map, sslid_service_list[service_number]->hash_list, sslid_service_list[service_number]->maxlist);
875 /*-------- DEBUG LOG --------*/
876 if (sslid_protomod.get_log_level != NULL &&
877 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_SYSTEM_MEMORY)) {
878 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,30, "free: %p",
879 sslid_service_list[service_number]);
881 /*------ DEBUG LOG END ------*/
883 free(sslid_service_list[service_number]);
884 sslid_service_list[service_number] = NULL;
891 /* sslid service was not found */
892 if (free_flag == 0) {
893 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,100, "Could not find such service handle's sslid service.");
899 /*-------- DEBUG LOG --------*/
900 if (sslid_protomod.get_log_level != NULL &&
901 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
902 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,116,
903 "out_function: int destroy(handle_t srv_handle):return_value=%d",
906 /*------ DEBUG LOG END ------*/
912 * Destroy sslid service argument
913 * @param[in] sslid_arg sslid service argument
917 destroy_sa(void** sslid_arg)
919 /*-------- DEBUG LOG --------*/
920 if (sslid_protomod.get_log_level != NULL &&
921 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
922 char sslid_arg_str[DEBUG_STR_LEN] = {0};
923 if (sslid_arg != NULL) {
924 l7vs_sslid_service_arg_c_str(sslid_arg_str, (struct l7vs_sslid_service_arg*) *sslid_arg);
927 strncpy(sslid_arg_str, "NULL", DEBUG_STR_LEN);
929 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,117,
930 "in_function: void destroy_sa(void** sslid_arg):sslid_arg=&(&(%s))",
933 /*------ DEBUG LOG END ------*/
936 if (sslid_arg == NULL) {
937 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,101, "Arg(sslid_arg) is NULL pointer.");
939 else if (*sslid_arg == NULL) {
940 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,102, "Arg(*sslid_arg) is NULL pointer.");
943 /*-------- DEBUG LOG --------*/
944 if (sslid_protomod.get_log_level != NULL &&
945 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_SYSTEM_MEMORY)) {
946 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,31, "free: %p",
949 /*------ DEBUG LOG END ------*/
952 free((struct l7vs_sslid_service_arg*) *sslid_arg);
956 /*-------- DEBUG LOG --------*/
957 if (sslid_protomod.get_log_level != NULL &&
958 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
959 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,118,
960 "out_function: void destroy_sa(void** sslid_arg)");
962 /*------ DEBUG LOG END ------*/
966 * Create strings for service list of l7vsadm
967 * @param[out] srv_arg_mt service argument struct
968 * @param[in] srv_handle a unique service ID
969 * @retval 0 successfully create strings
970 * @retval -1 some errors occur.
973 service_arg(struct l7vs_service_arg_multi* srv_arg_mt, handle_t srv_handle)
975 struct l7vs_sslid_service* sslid_service;
976 struct l7vs_sslid_service_arg s_sarg;
977 char sslid_argument[SERVICE_ARG_MAXSIZE];
978 int return_value = 0;
980 /*-------- DEBUG LOG --------*/
981 if (sslid_protomod.get_log_level != NULL &&
982 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
983 char srv_arg_mt_str[DEBUG_STR_LEN] = {0};
984 l7vs_service_arg_multi_c_str(srv_arg_mt_str, srv_arg_mt);
985 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,119,
986 "in_function: int service_arg(struct l7vs_service_arg_multi* srv_arg_mt, "
987 "handle_t srv_handle):srv_arg_mt=&(%s), srv_handle=%u",
988 srv_arg_mt_str, srv_handle);
990 /*------ DEBUG LOG END ------*/
993 if (srv_arg_mt == NULL) {
994 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,103, "Arg(srv_arg_mt) is NULL pointer.");
996 goto service_arg_out;
999 /* search service that has such a service ID */
1000 sslid_service = l7vs_protomod_sslid_search_service(srv_handle);
1002 /*-------- DEBUG LOG --------*/
1003 if (sslid_protomod.get_log_level != NULL &&
1004 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1005 char sslid_str[DEBUG_STR_LEN] = {0};
1006 l7vs_sslid_service_c_str(sslid_str, sslid_service);
1007 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,120, "pointer assign: sslid_service=&(%s)",
1010 /*------ DEBUG LOG END ------*/
1012 if (sslid_service == NULL) {
1013 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,104, "Could not find such service handle's sslid service.");
1015 goto service_arg_out;
1018 /* initialize argument strings */
1019 memset(sslid_argument, 0, SERVICE_ARG_MAXSIZE);
1021 /* set sslid args to service argument struct */
1022 srv_arg_mt->srv_arg.reschedule = sslid_service->reschedule;
1024 /* create long argument (l7vsadm option -l) */
1025 strncpy(srv_arg_mt->srv_arg.protomod_key_string, sslid_argument, 256);
1027 /* create verbose argument (l7vsadm option -V) */
1028 snprintf(sslid_argument + strlen(sslid_argument), SERVICE_ARG_MAXSIZE - strlen(sslid_argument),
1029 "--timeout %d --maxlist %d", sslid_service->timeout, sslid_service->maxlist);
1030 strncpy(srv_arg_mt->srv_arg.protomod_opt_string, sslid_argument, 512);
1032 /* set option value */
1033 s_sarg.timeout = sslid_service->timeout;
1034 s_sarg.maxlist = sslid_service->maxlist;
1035 s_sarg.reschedule = sslid_service->reschedule;
1037 memcpy(srv_arg_mt->protomod_arg, &s_sarg, sizeof(struct l7vs_sslid_service_arg));
1039 /*-------- DEBUG LOG --------*/
1040 if (sslid_protomod.get_log_level != NULL &&
1041 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1042 char sslid_arg_str[DEBUG_STR_LEN] = {0};
1043 l7vs_sslid_service_arg_c_str(sslid_arg_str, &s_sarg);
1044 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,121,
1045 "pointer assign: srv_arg_mt->protomod_arg=&(%s)", sslid_arg_str);
1047 /*------ DEBUG LOG END ------*/
1050 /*-------- DEBUG LOG --------*/
1051 if (sslid_protomod.get_log_level != NULL &&
1052 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1053 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,122,
1054 "out_function: int service_arg(struct l7vs_service_arg_multi* srv_arg_mt, "
1055 "handle_t srv_handle):return_value=%d", return_value);
1057 /*------ DEBUG LOG END ------*/
1059 return return_value;
1063 * Parse l7vsadm options to sslid argument
1064 * @param[out] sslid_arg sslid service argument struct
1065 * @param[in] argc number of l7vsadm argument
1066 * @param[in] argv l7vsadm argument list
1067 * @retval 0 successfully parse argument
1068 * @retval -1 some errors occur.
1071 parse(void* sslid_arg, int argc, char* argv[])
1073 struct l7vs_sslid_service_arg* sslid_service_arg;
1074 static struct option opt[] = {
1075 {"timeout", required_argument, NULL, 'T'},
1076 {"maxlist", required_argument, NULL, 'M'},
1077 {"reschedule", no_argument, NULL, 'R'},
1078 {"no-reschedule", no_argument, NULL, 'N'},
1082 unsigned long buffer;
1083 int timeout_flag = 0;
1084 int maxlist_flag = 0;
1085 int reschedule_flag = 0;
1086 int return_value = 0;
1088 /*-------- DEBUG LOG --------*/
1089 if (sslid_protomod.get_log_level != NULL &&
1090 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1092 char argv_str[DEBUG_STR_LEN] = {0};
1093 char sslid_arg_str[DEBUG_STR_LEN] = {0};
1094 l7vs_sslid_service_arg_c_str(sslid_arg_str, (struct l7vs_sslid_service_arg*) sslid_arg);
1097 snprintf(argv_str, DEBUG_STR_LEN, "NULL");
1099 for (i = 0; i < argc; i++) {
1100 snprintf(argv_str, DEBUG_STR_LEN, "%sargv[%d]=\"%s\", ", argv_str, i, argv[i]);
1102 i = strnlen(argv_str, DEBUG_STR_LEN);
1104 argv_str[i - 2] = '\0';
1106 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,123,
1107 "in_function: int parse(void* sslid_arg, int argc, char* argv[]):sslid_arg=&(%s), "
1108 "argc=%d, %s", sslid_arg_str, argc, argv_str);
1110 /*------ DEBUG LOG END ------*/
1113 if (sslid_arg == NULL) {
1114 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,105, "Arg(sslid_arg) is NULL pointer.");
1119 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,106, "Arg(argv) is NULL pointer.");
1124 sslid_service_arg = (struct l7vs_sslid_service_arg*) sslid_arg;
1127 /* check all argument */
1128 while ((c = getopt_long(argc, argv, "T:M:RN", opt, NULL)) != -1) {
1130 /* --timeout / -T */
1132 if (sscanf(optarg, "%lu", &buffer) == 0) {
1133 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,107,
1134 "-T/--timeout option value '%s' is invalid.", optarg);
1138 if (buffer > INT_MAX) {
1139 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,108,
1140 "-T/--timeout option value '%s' is too large.", optarg);
1145 sslid_service_arg->timeout = buffer;
1149 /* --maxlist / -M */
1151 if (sscanf(optarg, "%lu", &buffer) == 0) {
1152 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,109,
1153 "-M/--maxlist option value '%s' is invalid.", optarg);
1157 if (buffer > INT_MAX) {
1158 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,110,
1159 "-M/--maxlist option value '%s' is too large.", optarg);
1164 sslid_service_arg->maxlist = buffer;
1168 /* --reschedule / -R */
1171 sslid_service_arg->reschedule = 1;
1175 /* --no-reschedule / -N */
1177 /* reschedule off */
1178 sslid_service_arg->reschedule = 0;
1184 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,111, "Option error.");
1190 /* when set both -R and -N at the same time */
1191 if (reschedule_flag > 1) {
1192 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,112,
1193 "You should choose either reschdule or no-reschedule.");
1198 if (timeout_flag > 1) {
1199 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,113,
1200 "Cannot set multiple option '--timeout/-T'.");
1204 if (maxlist_flag > 1) {
1205 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,114,
1206 "Cannot set multiple option '--maxlist/-M'.");
1211 /* set default no reschedule */
1212 if (reschedule_flag == 0) {
1213 sslid_service_arg->reschedule = 0;
1216 /* set default options */
1217 if (timeout_flag == 0) {
1218 sslid_service_arg->timeout = 3600;
1220 if (maxlist_flag == 0 || sslid_service_arg->maxlist == 0) {
1221 sslid_service_arg->maxlist = 1024;
1225 /*-------- DEBUG LOG --------*/
1226 if (sslid_protomod.get_log_level != NULL &&
1227 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1228 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,124,
1229 "out_function: int parse(void* sslid_arg, int argc, char* argv[]):return_value=%d",
1232 /*------ DEBUG LOG END ------*/
1234 return return_value;
1238 * Search sslid service from sslid service list using service handle
1239 * @param[in] service_handle a unique service ID
1240 * @return sslid service struct when service was found. NULL when service was not found.
1242 static struct l7vs_sslid_service*
1243 l7vs_protomod_sslid_search_service(handle_t service_handle)
1245 /* sslid service list counter */
1246 int service_number = 0;
1247 struct l7vs_sslid_service* return_value = NULL;
1249 /*-------- DEBUG LOG --------*/
1250 if (sslid_protomod.get_log_level != NULL &&
1251 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1252 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,125,
1253 "in_function: struct l7vs_sslid_service* l7vs_protomod_sslid_search_service(handle_t service_handle):"
1254 "service_handle=%d", service_handle);
1256 /*------ DEBUG LOG END ------*/
1258 /* check all sslid service list */
1259 for (service_number = 0; service_number < SSLID_SERVICE_NUMBER; ++service_number) {
1260 /* found the service has same service handle */
1261 if (sslid_service_list[service_number] != NULL &&
1262 sslid_service_list[service_number]->service_handle == service_handle) {
1263 return_value = sslid_service_list[service_number];
1268 /*-------- DEBUG LOG --------*/
1269 if (sslid_protomod.get_log_level != NULL &&
1270 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1271 char ssl_str[DEBUG_STR_LEN] = {0};
1272 l7vs_sslid_service_c_str(ssl_str, return_value);
1273 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,126,
1274 "out_function: struct l7vs_sslid_service* l7vs_protomod_sslid_search_service(handle_t service_handle):"
1275 "return_value=&(%s)", ssl_str);
1277 /*------ DEBUG LOG END ------*/
1279 return return_value;
1283 * Create sslid service.
1285 * @return sslid service struct when create a service. NULL when cannot create service.
1287 static struct l7vs_sslid_service*
1288 l7vs_protomod_sslid_create_service()
1290 int service_number = 0;
1291 struct l7vs_sslid_service* return_value = NULL;
1293 /*-------- DEBUG LOG --------*/
1294 if (sslid_protomod.get_log_level != NULL &&
1295 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1296 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,127,
1297 "in_function: struct l7vs_sslid_service* l7vs_protomod_sslid_create_service()");
1299 /*------ DEBUG LOG END ------*/
1301 /* check all sslid service list */
1302 for (service_number = 0; service_number < SSLID_SERVICE_NUMBER - 1; ++service_number) {
1303 /* if pointer that does not point NULL exists ... */
1304 if (sslid_service_list[service_number] == NULL) {
1305 /* create a service at empty pointer */
1306 sslid_service_list[service_number] = (struct l7vs_sslid_service*) calloc(1, sizeof(struct l7vs_sslid_service));
1308 /*-------- DEBUG LOG --------*/
1309 if (sslid_protomod.get_log_level != NULL &&
1310 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_SYSTEM_MEMORY)) {
1311 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,32, "calloc: addr=%p, size=%ld",
1312 sslid_service_list[service_number], (unsigned long int) sizeof(struct l7vs_sslid_service));
1314 /*------ DEBUG LOG END ------*/
1316 if (sslid_service_list[service_number] == NULL) {
1317 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,25, "Could not allocate memory.");
1318 goto create_service_out;
1320 return_value = sslid_service_list[service_number];
1321 goto create_service_out;
1325 /* all service list is full */
1326 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,115, "sslid service list is full.");
1329 /*-------- DEBUG LOG --------*/
1330 if (sslid_protomod.get_log_level != NULL &&
1331 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1332 char ssl_str[DEBUG_STR_LEN] = {0};
1333 l7vs_sslid_service_c_str(ssl_str, return_value);
1334 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,128,
1335 "out_function: struct l7vs_sslid_service* l7vs_protomod_sslid_create_service():"
1336 "return_value=&(%s)", ssl_str);
1338 /*------ DEBUG LOG END ------*/
1340 return return_value;
1344 * Create temporary sslid service.
1346 * @return sslid service struct when create a service. NULL when cannot create service.
1348 static struct l7vs_sslid_service*
1349 l7vs_protomod_sslid_create_temp_service()
1351 struct l7vs_sslid_service* return_value = NULL;
1353 /*-------- DEBUG LOG --------*/
1354 if (sslid_protomod.get_log_level != NULL &&
1355 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1356 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,129,
1357 "in_function: struct l7vs_sslid_service* l7vs_protomod_sslid_create_temp_service()");
1359 /*------ DEBUG LOG END ------*/
1361 /* if pointer that does not point NULL exists ... */
1362 if (sslid_service_list[SSLID_SERVICE_NUMBER - 1] != NULL) {
1363 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,116, "Temporary sslid service is being used by other process.");
1364 goto create_temp_service_out;
1367 /* create temp service */
1368 sslid_service_list[SSLID_SERVICE_NUMBER - 1] = (struct l7vs_sslid_service*) calloc(1, sizeof(struct l7vs_sslid_service));
1370 /*-------- DEBUG LOG --------*/
1371 if (sslid_protomod.get_log_level != NULL &&
1372 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_SYSTEM_MEMORY)) {
1373 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,33, "calloc: addr=%p, size=%ld",
1374 sslid_service_list[SSLID_SERVICE_NUMBER - 1], (unsigned long int) sizeof(struct l7vs_sslid_service));
1376 /*------ DEBUG LOG END ------*/
1378 if (sslid_service_list[SSLID_SERVICE_NUMBER - 1] == NULL) {
1379 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_SYSTEM_MEMORY,26, "Could not allocate memory");
1380 goto create_temp_service_out;
1383 return_value = sslid_service_list[SSLID_SERVICE_NUMBER - 1];
1385 create_temp_service_out:
1386 /*-------- DEBUG LOG --------*/
1387 if (sslid_protomod.get_log_level != NULL &&
1388 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1389 char ssl_str[DEBUG_STR_LEN] = {0};
1390 l7vs_sslid_service_c_str(ssl_str, return_value);
1391 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,130,
1392 "out_function: struct l7vs_sslid_service* l7vs_protomod_sslid_create_service():"
1393 "return_value=&(%s)", ssl_str);
1395 /*------ DEBUG LOG END ------*/
1397 return return_value;
1401 * Read replication area and set session data.
1402 * @param[in] sslid_service read this sslid service's session.
1405 static void l7vs_protomod_sslid_read_replication_data(struct l7vs_sslid_service* sslid_service, struct l7vs_service* srv)
1407 struct replication_header* head;
1408 struct replication_header* pick = NULL;
1409 unsigned int data_size = 0;
1410 unsigned int used = 0;
1411 void* data_addr = NULL;
1415 /*-------- DEBUG LOG --------*/
1416 if (sslid_protomod.get_log_level != NULL &&
1417 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1418 char ssl_str[DEBUG_STR_LEN] = {0};
1419 l7vs_sslid_service_c_str(ssl_str, sslid_service);
1420 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,131,
1421 "in_function: void l7vs_protomod_sslid_read_replication_data(struct "
1422 "l7vs_sslid_service* sslid_service):sslid_service=&(%s)", ssl_str);
1424 /*------ DEBUG LOG END ------*/
1427 if (sslid_service == NULL) {
1428 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL, 294, "Arg(sslid_service) is NULL pointer.");
1429 goto read_replication_data_out;
1431 if (sslid_service->session == NULL) {
1432 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL, 295, "Arg(sslid_service->session) is NULL pointer.");
1433 goto read_replication_data_out;
1436 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL, 296,
1437 "Service that has handle(%d) is not found.", sslid_service->service_handle);
1438 goto read_replication_data_out;
1440 if (srv->lsock == NULL) {
1441 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL, 297,
1442 "Conn of service that has handle(%d) is NULL pointer.", sslid_service->service_handle);
1443 goto read_replication_data_out;
1446 /* get replication area address */
1447 data_addr = sslid_protomod.replication_pay_memory(sslid_protomod.modname, &data_size);
1448 if (data_addr == NULL || data_size <= 0)
1449 goto read_replication_data_out;
1451 /* check replication area header */
1452 for (srv_num = 0; srv_num < SSLID_SERVICE_NUMBER; srv_num++) {
1453 head = (struct replication_header*) data_addr + srv_num;
1456 if (data_size * DATA_SIZE < sizeof(struct replication_header) * (SSLID_SERVICE_NUMBER - 1) + used) {
1457 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL, 298, "Over replication area.");
1458 goto read_replication_data_out;
1461 if (pick == NULL && head->size == 0)
1463 if (exist >= 0 && pick != NULL)
1466 /* match ip and port, this is pre-used session information */
1467 if (memcmp(&head->sin_addr, &srv->lsock->addr.sin_addr, sizeof(struct in_addr)) == 0 &&
1468 head->sin_port == srv->lsock->addr.sin_port) {
1474 head = (struct replication_header*) data_addr + exist;
1476 /* restore session information */
1477 if (sslid_service->maxlist * sizeof(struct ssl_session) > head->size) {
1478 // resize if maxlist set bigger than old
1480 /* area size check */
1481 if (sizeof(struct replication_header) * (SSLID_SERVICE_NUMBER - 1) +
1482 used + sslid_service->maxlist * sizeof(struct ssl_session) > data_size * DATA_SIZE) {
1483 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL, 299,
1484 "Replication area is full.");
1485 goto read_replication_data_out;
1488 memcpy(sslid_service->session, (char*) data_addr + head->offset, head->size);
1489 memset(sslid_service->replication_addr, 0, head->size);
1490 sslid_service->replication_addr = (char*) data_addr +
1491 sizeof(struct replication_header) * (SSLID_SERVICE_NUMBER - 1) + used;
1492 pick->sin_addr = srv->lsock->addr.sin_addr;
1493 pick->sin_port = srv->lsock->addr.sin_port;
1494 pick->size = sslid_service->maxlist * sizeof(struct ssl_session);
1495 pick->offset = sizeof(struct replication_header) * (SSLID_SERVICE_NUMBER - 1) + used;
1497 /*-------- DEBUG LOG --------*/
1498 if (sslid_protomod.get_log_level != NULL &&
1499 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1500 char head_str[DEBUG_STR_LEN];
1501 replication_header_c_str(head_str, pick);
1502 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL, 318,
1503 "Write replication area: head=(%s)", head_str);
1505 /*------ DEBUG LOG END ------*/
1507 // you should garbage old session area...
1511 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL, 300,
1512 "Replication area is full.");
1513 goto read_replication_data_out;
1517 sslid_service->replication_addr = (char*) data_addr + head->offset;
1518 memcpy(sslid_service->session, sslid_service->replication_addr,
1519 sslid_service->maxlist * sizeof(struct ssl_session));
1520 head->size = sslid_service->maxlist * sizeof(struct ssl_session);
1522 /*-------- DEBUG LOG --------*/
1523 if (sslid_protomod.get_log_level != NULL &&
1524 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1525 char head_str[DEBUG_STR_LEN];
1526 replication_header_c_str(head_str, head);
1527 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL, 319,
1528 "Write replication area: head=(%s)", head_str);
1530 /*------ DEBUG LOG END ------*/
1536 /* area size check */
1537 if (sizeof(struct replication_header) * (SSLID_SERVICE_NUMBER - 1) +
1538 used + sslid_service->maxlist * sizeof(struct ssl_session) > data_size * DATA_SIZE) {
1539 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL, 301,
1540 "Replication area is full.");
1541 goto read_replication_data_out;
1544 /* initialize replication information */
1545 sslid_service->replication_addr = (char*) data_addr +
1546 sizeof(struct replication_header) * (SSLID_SERVICE_NUMBER - 1) + used;
1547 pick->sin_addr = srv->lsock->addr.sin_addr;
1548 pick->sin_port = srv->lsock->addr.sin_port;
1549 pick->size = sslid_service->maxlist * sizeof(struct ssl_session);
1550 pick->offset = sizeof(struct replication_header) * (SSLID_SERVICE_NUMBER - 1) + used;
1552 /*-------- DEBUG LOG --------*/
1553 if (sslid_protomod.get_log_level != NULL &&
1554 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1555 char head_str[DEBUG_STR_LEN];
1556 replication_header_c_str(head_str, pick);
1557 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL, 320,
1558 "Write replication area: head=(%s)", head_str);
1560 /*------ DEBUG LOG END ------*/
1564 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL, 302,
1565 "Replication area is full.");
1566 goto read_replication_data_out;
1570 read_replication_data_out:
1571 /*-------- DEBUG LOG --------*/
1572 if (sslid_protomod.get_log_level != NULL &&
1573 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1574 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,132,
1575 "out_function: l7vs_protomod_sslid_read_replication_data(struct "
1576 "l7vs_sslid_service* sslid_service)");
1578 /*------ DEBUG LOG END ------*/
1582 * Write session data to replication area.
1583 * @param[in] sslid_service save this sslid service's session.
1586 static void l7vs_protomod_sslid_write_replication_data(struct l7vs_sslid_service* sslid_service)
1588 /*-------- DEBUG LOG --------*/
1589 if (sslid_protomod.get_log_level != NULL &&
1590 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1591 char ssl_str[DEBUG_STR_LEN] = {0};
1592 l7vs_sslid_service_c_str(ssl_str, sslid_service);
1593 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,133,
1594 "in_function: void l7vs_protomod_sslid_write_replication_data(struct "
1595 "l7vs_sslid_service* sslid_service):sslid_service=&(%s)", ssl_str);
1597 /*------ DEBUG LOG END ------*/
1600 if (sslid_service == NULL) {
1601 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL, 303, "Arg(sslid_service) is NULL pointer.");
1602 goto write_replication_data_out;
1604 if (sslid_service->session == NULL) {
1605 PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL, 304, "Arg(sslid_service->session) is NULL pointer.");
1606 goto write_replication_data_out;
1608 /* no replicate setting */
1609 if (sslid_service->replication_addr == NULL) {
1610 goto write_replication_data_out;
1613 /* copy session data */
1614 memcpy(sslid_service->replication_addr, sslid_service->session,
1615 sizeof(struct ssl_session) * sslid_service->maxlist);
1617 /*-------- DEBUG LOG --------*/
1618 if (sslid_protomod.get_log_level != NULL &&
1619 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1620 char session_str[DEBUG_STR_LEN];
1621 ssl_session_c_str(session_str, (struct ssl_session*) sslid_service->replication_addr);
1622 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL, 321, "Write replication area: session=(%s)",
1625 /*------ DEBUG LOG END ------*/
1627 write_replication_data_out:
1628 /*-------- DEBUG LOG --------*/
1629 if (sslid_protomod.get_log_level != NULL &&
1630 LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
1631 PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,134,
1632 "out_function: void l7vs_protomod_sslid_write_replication_data(struct "
1633 "l7vs_sslid_service* sslid_service)");
1635 /*------ DEBUG LOG END ------*/
1639 * Serialize struct l7vs_sslid_service for debug log.
1640 * @param[out] buf serialized string
1641 * @param[in] sslid l7vs_sslid_service struct
1643 static void l7vs_sslid_service_c_str(char* buf, struct l7vs_sslid_service* sslid) {
1644 if (sslid == NULL) {
1645 snprintf(buf, DEBUG_STR_LEN, "NULL");
1648 char session_str[DEBUG_STR_LEN] = {0};
1649 ssl_session_c_str(session_str, sslid->session);
1650 snprintf(buf, DEBUG_STR_LEN, "service_handle=%d, timeout=%d, maxlist=%d, "
1651 "session=(%s), replication_addr=%p, reschedule=%d", sslid->service_handle,
1652 sslid->timeout, sslid->maxlist, session_str, sslid->replication_addr,
1658 * Serialize struct l7vs_sslid_service_arg for debug log.
1659 * @param[out] buf serialized string
1660 * @param[in] sslid_arg l7vs_sslid_service_arg struct
1662 void l7vs_sslid_service_arg_c_str(char* buf, struct l7vs_sslid_service_arg* sslid_arg) {
1663 if (sslid_arg == NULL) {
1664 snprintf(buf, DEBUG_STR_LEN, "NULL");
1667 snprintf(buf, DEBUG_STR_LEN, "timeout=%d, maxlist=%d, reschedule=%d",
1668 sslid_arg->timeout, sslid_arg->maxlist, sslid_arg->reschedule);
1673 * Serialize struct ssl_session for debug log.
1674 * @param[out] buf serialized string
1675 * @param[in] session ssl_session struct
1677 static void ssl_session_c_str(char* buf, struct ssl_session* session) {
1678 if (session == NULL) {
1679 snprintf(buf, DEBUG_STR_LEN, "NULL");
1682 char dest_str[DEBUG_STR_LEN] = {0};
1683 char session_str[SSLID_LENGTH * 2 + 1];
1684 l7vs_dest_c_str(dest_str, &session->dest);
1685 id_c_str(session_str, session->id, session->id_len); // Add length parameter 2009.4.8 T.Motoda@NTTR
1686 snprintf(buf, DEBUG_STR_LEN, "id=%s, dest=(%s), last_time=%d, valid=%d",
1687 session_str, dest_str, (u_int) session->last_time, (int)session->valid);
1692 * Serialize struct replication_header for debug log.
1693 * @param[out] buf serialized string
1694 * @param[in] head replication_header struct
1696 static void replication_header_c_str(char* buf, struct replication_header* head) {
1698 snprintf(buf, DEBUG_STR_LEN, "NULL");
1701 snprintf(buf, DEBUG_STR_LEN, "sin_addr=(s_addr=%ld), sin_port=%d, size=%d, offset=%d",
1702 (u_long) head->sin_addr.s_addr, head->sin_port, head->size, head->offset);
1707 * Convert SSL session ID (binary to hex)
1708 * @param[out] buf hex string
1709 * @param[in] id SSL session ID
1710 * @param[in] id_len SSL session ID length 2009.4.8 by T.Motoda@NTTR
1712 static void id_c_str(char* buf, char* id, int id_len) {
1715 snprintf(buf, DEBUG_STR_LEN, "NULL");
1718 for (i = 0; i < id_len; i++) {
1719 snprintf(buf + i * 2, DEBUG_STR_LEN - i * 2, "%02X", (unsigned char)id[i]);