OSDN Git Service

Merge commit 'sfj/autotools-fix'; commit 'sfj/modulefix'; commit 'sfj/sslid-sslidleng...
[ultramonkey-l7/ultramonkey-l7-v2.git] / module / protocol / protomod_sslid.c
index 5af99c8..00f259c 100644 (file)
@@ -6,6 +6,7 @@
  * 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
@@ -45,8 +46,10 @@ static void  fini(void);
 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);
@@ -65,34 +68,35 @@ static void l7vs_sslid_service_c_str(char*, struct l7vs_sslid_service*);
 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 */
 };
 
 /*!
@@ -414,8 +418,8 @@ compare(handle_t srv_handle1, handle_t srv_handle2)
  * @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;
@@ -448,10 +452,10 @@ match_cldata(struct l7vs_service* srv, struct l7vs_conn* conn,
                        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 ------*/
 
@@ -459,32 +463,27 @@ match_cldata(struct l7vs_service* srv, struct l7vs_conn* conn,
        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 */
@@ -503,13 +502,13 @@ match_cldata(struct l7vs_service* srv, struct l7vs_conn* conn,
        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 */
@@ -523,31 +522,31 @@ match_cldata(struct l7vs_service* srv, struct l7vs_conn* conn,
        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) {
@@ -556,22 +555,20 @@ match_cldata(struct l7vs_service* srv, struct l7vs_conn* conn,
                
        }
 
-       *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);
        }
@@ -581,6 +578,105 @@ match_cldata_out:
 }
 
 /*!
+ * 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.
@@ -690,26 +786,26 @@ analyze_rsdata(struct l7vs_service* srv, struct l7vs_conn* conn,
 
        /* 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);
@@ -1586,7 +1682,7 @@ static void ssl_session_c_str(char* buf, struct ssl_session* session) {
                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);
        }
@@ -1611,15 +1707,17 @@ static void replication_header_c_str(char* buf, struct replication_header* head)
  * 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]);
+
                }
        }
 }