* 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]);
+
}
}
}