* L7VSD: Linux Virtual Server for Layer7 Load Balancing
* Copyright (C) 2008 NTT COMWARE Corporation.
* Copyright (C) 2009 Shinya TAKEBAYASHI
+++ * Copyright (C) 2009 NTT Resonant Inc. O.Nakayama, T.Motoda.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
static int create(void*, handle_t);
static void* create_sa(struct l7vs_service_arg*);
static int compare(handle_t, handle_t);
-- -static int match_cldata(struct l7vs_service*, struct l7vs_conn*,
-- - char*, size_t*, struct l7vs_dest**, int*);
++ +static int select_dest(struct l7vs_service*, struct l7vs_conn*,
++ + char*, size_t*, struct l7vs_dest**);
++ +static int analyze_cldata(struct l7vs_service*, struct l7vs_conn*,
++ + char*, size_t*);
static int analyze_rsdata(struct l7vs_service*, struct l7vs_conn*,
char*, size_t*);
static int destroy(handle_t);
static void l7vs_sslid_service_arg_c_str(char*, struct l7vs_sslid_service_arg*);
static void ssl_session_c_str(char*, struct ssl_session*);
static void replication_header_c_str(char*, struct replication_header*);
--- static void id_c_str(char*, char*);
+++ static void id_c_str(char*, char*, int); /* add session id length param 2009.4.8 T.Motoda@NTTR */
struct l7vs_sslid_service* sslid_service_list[SSLID_SERVICE_NUMBER];
static struct l7vs_protomod sslid_protomod = {
-- - NULL, /* handle */
-- - "sslid", /* modname */
-- - 0, /* refcnt */
-- - 0, /* fast schedule */
-- - create, /* create function */
-- - compare, /* compare function */
-- - match_cldata, /* match_cldata function */
-- - analyze_rsdata, /* analyze_rsdata function */
-- - destroy, /* destroy function */
-- - fini, /* fini function */
-- - create_sa, /* create_sa function */
-- - service_arg, /* service_arg function */
-- - parse, /* parse function */
-- - destroy_sa, /* destroy_sa function */
-- - NULL, /* initialize function */
-- - NULL, /* finalize function */
-- - NULL, /* get_log_level function */
-- - NULL, /* put_log_debug function */
-- - NULL, /* put_log_info function */
-- - NULL, /* put_log_warn function */
-- - NULL, /* put_log_error function */
-- - NULL, /* put_log_fatal function */
-- - NULL /* replication_pay_memory function */
++ + NULL, /* handle */
++ + "sslid", /* modname */
++ + 0, /* refcnt */
++ + 0, /* fast schedule */
++ + create, /* create function */
++ + compare, /* compare function */
++ + select_dest, /* select_dest function */
++ + analyze_cldata, /* analyze_cldata function */
++ + analyze_rsdata, /* analyze_rsdata function */
++ + destroy, /* destroy function */
++ + fini, /* fini function */
++ + create_sa, /* create_sa function */
++ + service_arg, /* service_arg function */
++ + parse, /* parse function */
++ + destroy_sa, /* destroy_sa function */
++ + NULL, /* initialize function */
++ + NULL, /* finalize function */
++ + NULL, /* get_log_level function */
++ + NULL, /* put_log_debug function */
++ + NULL, /* put_log_info function */
++ + NULL, /* put_log_warn function */
++ + NULL, /* put_log_error function */
++ + NULL, /* put_log_fatal function */
++ + NULL /* replication_pay_memory function */
};
/*!
* @retval -1 some errors occur.
*/
static int
-- -match_cldata(struct l7vs_service* srv, struct l7vs_conn* conn,
-- - char* request, size_t* len, struct l7vs_dest** dest, int* tcps)
++ +select_dest(struct l7vs_service* srv, struct l7vs_conn* conn,
++ + char* request, size_t* len, struct l7vs_dest** dest)
{
struct l7vs_sslid_service* sslid_service;
int i;
strncpy(len_str, "NULL", DEBUG_STR_LEN);
}
PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,103,
-- - "in_function: int match_cldata(struct l7vs_service* srv, struct l7vs_conn* conn, "
-- - "char* request, size_t* len, struct l7vs_dest** dest, int* tcps):srv=&(%s), conn=&(%s), "
-- - "request=\"%s\", len=&(%s), dest=&(&(%s)), tcps=&(%d)",
-- - srv_str, conn_str, request, len_str, dest_str, *tcps);
++ + "in_function: int select_dest(struct l7vs_service* srv, struct l7vs_conn* conn, "
++ + "char* request, size_t* len, struct l7vs_dest** dest):srv=&(%s), conn=&(%s), "
++ + "request=\"%s\", len=&(%s), dest=&(&(%s))",
++ + srv_str, conn_str, request, len_str, dest_str);
}
/*------ DEBUG LOG END ------*/
if (srv == NULL) {
PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,83, "Arg(srv) is NULL pointer.");
return_value = -1;
-- - goto match_cldata_out;
++ + goto select_dest_out;
}
if (srv->pm == NULL) {
PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,84, "Arg(srv->pm) is NULL pointer.");
return_value = -1;
-- - goto match_cldata_out;
++ + goto select_dest_out;
}
if (request == NULL) {
PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,85, "Arg(request) is NULL pointer.");
return_value = -1;
-- - goto match_cldata_out;
++ + goto select_dest_out;
}
if (len == NULL) {
PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,86, "Arg(len) is NULL pointer.");
return_value = -1;
-- - goto match_cldata_out;
++ + goto select_dest_out;
}
if (dest == NULL) {
PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,87, "Arg(dest) is NULL pointer.");
return_value = -1;
-- - goto match_cldata_out;
-- - }
-- - if (tcps == NULL) {
-- - PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,88, "Arg(tcps) is NULL pointer.");
-- - return_value = -1;
-- - goto match_cldata_out;
++ + goto select_dest_out;
}
/* search service that has such a service ID */
if (sslid_service == NULL) {
PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,89, "Could not find such service handle's sslid service.");
return_value = -1;
-- - goto match_cldata_out;
++ + goto select_dest_out;
}
if (sslid_service->session == NULL) {
PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,90,
"Service has NULL pointer session.");
return_value = -1;
-- - goto match_cldata_out;
++ + goto select_dest_out;
}
/* read replication data */
if (ret != 0){
PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,91, "Could not initialize protomod.");
return_value = -1;
-- - goto match_cldata_out;
++ + goto select_dest_out;
}
/* check payload */
if (
--- *len > 75 &&
+++ *len > 44 && // Check if minimum length 2009.4.8 O.Nakayama@NTTR and T.Motoda@NTTR
(
(request[1] == 0x03 && request[2] == 0x00 && request[9] == 0x03 && request [10] == 0x00) || // SSL v3
(request[1] == 0x03 && request[2] == 0x01 && request[9] == 0x03 && request [10] == 0x01) // TLS v1
) &&
request[5] == 0x01 && // Client Hello
--- request[43] == 0x20 // Session ID Length
+++ (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
) {
/*-------- DEBUG LOG --------*/
if (sslid_protomod.get_log_level != NULL &&
LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
char id_str[DEBUG_STR_LEN] = {0};
--- id_c_str(id_str, &request[44]);
+++ id_c_str(id_str, &request[44], request[43]); // Add length parameter 2009.4.8 T.Motoda@NTTR
PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,105,
"Client Hello/SessionID=%s", id_str);
}
/*------ DEBUG LOG END ------*/
hash_setPointer(sslid_service->hash_map, sslid_service->hash_list, sslid_service->maxlist);
--- id_c_str(id_str, &request[44]);
+++ id_c_str(id_str, &request[44], request[43]); // Add length parameter 2009.4.8 T.Motoda@NTTR
searchret = hash_search(id_str, &tmpdest);
if (searchret == 0) {
}
-- - *tcps = 0;
-- -
-- - /* finalize, always set reschedule flag */
++ + /* finalize */
ret = srv->pm->finalize(srv, conn, request, *len, dest, sslid_service->reschedule);
if (ret != 0){
PUT_LOG_INFO(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,11, "Could not finalize protomod. (Realserver decision failure)");
return_value = -1;
-- - goto match_cldata_out;
++ + goto select_dest_out;
}
-- -match_cldata_out:
++ +select_dest_out:
/*-------- DEBUG LOG --------*/
if (sslid_protomod.get_log_level != NULL &&
LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,107,
-- - "out_function: int match_cldata(struct l7vs_service* srv, struct l7vs_conn* conn, "
++ + "out_function: int select_dest(struct l7vs_service* srv, struct l7vs_conn* conn, "
"char* request, size_t* len, struct l7vs_dest** dest, int* tcps):return_value=%d",
return_value);
}
}
/*!
++ + * Do nothing
++ + * @param[in] srv service struct include service handle, protocol module and schedule module.
++ + * @param[in] conn connection data.
++ + * @param[in] request packet data from client
++ + * @param[in] len length of packet data
++ + * @retval 0 successfully check packet data
++ + * @retval -1 some errors occur.
++ + */
++ +static int
++ +analyze_cldata(struct l7vs_service* srv, struct l7vs_conn* conn,
++ + char* request, size_t* len)
++ +{
++ + struct l7vs_sslid_service* sslid_service;
++ + int return_value = 0;
++ +
++ + /*-------- DEBUG LOG --------*/
++ + if (sslid_protomod.get_log_level != NULL &&
++ + LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
++ + char srv_str[DEBUG_STR_LEN] = {0};
++ + char conn_str[DEBUG_STR_LEN] = {0};
++ + char dest_str[DEBUG_STR_LEN] = {0};
++ + char len_str[DEBUG_STR_LEN] = {0};
++ + l7vs_service_c_str(srv_str, srv);
++ + l7vs_conn_c_str(conn_str, conn);
++ + if (len != NULL) {
++ + snprintf(len_str, DEBUG_STR_LEN, "%lu", (unsigned long int) *len);
++ + }
++ + else {
++ + strncpy(len_str, "NULL", DEBUG_STR_LEN);
++ + }
++ + PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,103,
++ + "in_function: int analyze_cldata(struct l7vs_service* srv, struct l7vs_conn* conn, "
++ + "char* request, size_t* len):srv=&(%s), conn=&(%s), "
++ + "request=\"%s\", len=&(%s)",
++ + srv_str, conn_str, request, len_str);
++ + }
++ + /*------ DEBUG LOG END ------*/
++ +
++ + /* check null */
++ + if (srv == NULL) {
++ + PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,83, "Arg(srv) is NULL pointer.");
++ + return_value = -1;
++ + goto analyze_cldata_out;
++ + }
++ + if (srv->pm == NULL) {
++ + PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,84, "Arg(srv->pm) is NULL pointer.");
++ + return_value = -1;
++ + goto analyze_cldata_out;
++ + }
++ + if (request == NULL) {
++ + PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,85, "Arg(request) is NULL pointer.");
++ + return_value = -1;
++ + goto analyze_cldata_out;
++ + }
++ + if (len == NULL) {
++ + PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,86, "Arg(len) is NULL pointer.");
++ + return_value = -1;
++ + goto analyze_cldata_out;
++ + }
++ +
++ + /* search service that has such a service ID */
++ + sslid_service = l7vs_protomod_sslid_search_service(srv->handle);
++ +
++ + /*-------- DEBUG LOG --------*/
++ + if (sslid_protomod.get_log_level != NULL &&
++ + LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
++ + char sslid_str[DEBUG_STR_LEN] = {0};
++ + l7vs_sslid_service_c_str(sslid_str, sslid_service);
++ + PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,104, "pointer assign: sslid_service=&(%s)",
++ + sslid_str);
++ + }
++ + /*------ DEBUG LOG END ------*/
++ +
++ + if (sslid_service == NULL) {
++ + PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,89, "Could not find such service handle's sslid service.");
++ + return_value = -1;
++ + goto analyze_cldata_out;
++ + }
++ + if (sslid_service->session == NULL) {
++ + PUT_LOG_ERROR(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,90,
++ + "Service has NULL pointer session.");
++ + return_value = -1;
++ + goto analyze_cldata_out;
++ + }
++ +
++ +analyze_cldata_out:
++ + /*-------- DEBUG LOG --------*/
++ + if (sslid_protomod.get_log_level != NULL &&
++ + LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
++ + PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,107,
++ + "out_function: int analyze_cldata(struct l7vs_service* srv, struct l7vs_conn* conn, "
++ + "char* request, size_t* len):return_value=%d", return_value);
++ + }
++ + /*------ DEBUG LOG END ------*/
++ +
++ + return return_value;
++ +}
++ +
++ +/*!
* Check and modify response packet.
* @param[in] srv service struct include service handle, protocol module and schedule module.
* @param[in] conn connection data.
/* check payload */
if (
--- *len > 75 &&
+++ *len > 44 && // Check if minimum length 2009.4.8 O.Nakayama and T.Motoda@NTTR
(
(response[1] == 0x03 && response[2] == 0x00 && response[9] == 0x03 && response [10] == 0x00) || // SSL v3
(response[1] == 0x03 && response[2] == 0x01 && response[9] == 0x03 && response [10] == 0x01) // TLS v1
) &&
response[5] == 0x02 && // Server Hello
--- response[43] == 0x20 // Session ID Length
+++ (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
) {
/*-------- DEBUG LOG --------*/
if (sslid_protomod.get_log_level != NULL &&
LOG_LV_DEBUG == sslid_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
char id_str[DEBUG_STR_LEN] = {0};
--- id_c_str(id_str, &response[44]);
+++ id_c_str(id_str, &response[44], response[43]); // Add length parameter 2009.4.8 T.Motoda@NTTR
PUT_LOG_DEBUG(sslid_protomod, LOG_CAT_L7VSD_PROTOCOL,111,
"Server Hello/SessionID=%s", id_str);
}
/*------ DEBUG LOG END ------*/
hash_setPointer(sslid_service->hash_map, sslid_service->hash_list, sslid_service->maxlist);
--- id_c_str(id_str, &response[44]);
+++ id_c_str(id_str, &response[44], response[43]); // Add length parameter 2009.4.8 T.Motoda@NTTR
hash_add(id_str, *conn->dest);
if (sslid_service->replication_addr) {
hash_construct_sessionlist(sslid_service);
char dest_str[DEBUG_STR_LEN] = {0};
char session_str[SSLID_LENGTH * 2 + 1];
l7vs_dest_c_str(dest_str, &session->dest);
--- id_c_str(session_str, session->id);
+++ id_c_str(session_str, session->id, session->id_len); // Add length parameter 2009.4.8 T.Motoda@NTTR
snprintf(buf, DEBUG_STR_LEN, "id=%s, dest=(%s), last_time=%d, valid=%d",
session_str, dest_str, (u_int) session->last_time, (int)session->valid);
}
* Convert SSL session ID (binary to hex)
* @param[out] buf hex string
* @param[in] id SSL session ID
+++ * @param[in] id_len SSL session ID length 2009.4.8 by T.Motoda@NTTR
*/
--- static void id_c_str(char* buf, char* id) {
+++ static void id_c_str(char* buf, char* id, int id_len) {
int i;
if (id == NULL) {
snprintf(buf, DEBUG_STR_LEN, "NULL");
}
else {
--- for (i = 0; i < SSLID_LENGTH; i++) {
--- snprintf(buf + i * 2, DEBUG_STR_LEN - i * 2, "%02X", (unsigned int)id[i]);
+++ for (i = 0; i < id_len; i++) {
+++ snprintf(buf + i * 2, DEBUG_STR_LEN - i * 2, "%02X", (unsigned char)id[i]);
+++
}
}
}