OSDN Git Service

Module bug fix.
[ultramonkey-l7/ultramonkey-l7-v2.git] / module / protocol / protomod_url.c
index 6831f22..003bff1 100644 (file)
@@ -77,8 +77,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);
@@ -102,7 +104,8 @@ static struct l7vs_protomod url_protomod = {
        0,              /* fast schedule */
        create,         /* create function */
        compare,        /* compare function */
-       match_cldata,   /* match_cldata function */
+       select_dest,    /* select_dest function */
+       analyze_cldata, /* analyze_cldata function */
        analyze_rsdata, /* analyze_rsdata function */
        destroy,        /* destroy function */
        fini,           /* fini function */
@@ -474,13 +477,12 @@ compare_out:
  * @param[in]  request packet data from client
  * @param[in]  len length of packet data
  * @param[out] dest destination (real server) list
- * @param[out] tcps TCP Splicer flag
  * @retval 0  successfully check packet data
  * @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_url_service *url_service;
        int ret;
@@ -520,17 +522,11 @@ match_cldata(struct l7vs_service *srv, struct l7vs_conn *conn,
                else {
                        strncpy(len_str, "NULL", DEBUG_STR_LEN);
                }
-               if (tcps != NULL) {
-                       snprintf(tcps_str, DEBUG_STR_LEN, "%d", *tcps);
-               }
-               else {
-                       strncpy(tcps_str, "NULL", DEBUG_STR_LEN);
-               }
                PUT_LOG_DEBUG(url_protomod, LOG_CAT_L7VSD_PROTOCOL,148,
-                   "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=&(%s)",
-                   srv_str, conn_str, request, len_str, dest_str, tcps_str);
+                   "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 ------*/
 
@@ -538,32 +534,27 @@ match_cldata(struct l7vs_service *srv, struct l7vs_conn *conn,
        if (srv == NULL) {
                PUT_LOG_ERROR(url_protomod, LOG_CAT_L7VSD_PROTOCOL,123, "Arg(srv) is NULL pointer.");
                return_value = -1;
-               goto match_cldata_out;
+               goto select_dest_out;
        }
        if (srv->pm == NULL) {
                PUT_LOG_ERROR(url_protomod, LOG_CAT_L7VSD_PROTOCOL,124, "Arg(srv->pm) is NULL pointer.");
                return_value = -1;
-               goto match_cldata_out;
+               goto select_dest_out;
        }
        if (request == NULL) {
                PUT_LOG_ERROR(url_protomod, LOG_CAT_L7VSD_PROTOCOL,125, "Arg(request) is NULL pointer.");
                return_value = -1;
-               goto match_cldata_out;
+               goto select_dest_out;
        }
        if (len == NULL) {
                PUT_LOG_ERROR(url_protomod, LOG_CAT_L7VSD_PROTOCOL,126, "Arg(len) is NULL pointer.");
                return_value = -1;
-               goto match_cldata_out;
+               goto select_dest_out;
        }
        if (dest == NULL) {
                PUT_LOG_ERROR(url_protomod, LOG_CAT_L7VSD_PROTOCOL,127, "Arg(dest) is NULL pointer.");
                return_value = -1;
-               goto match_cldata_out;
-       }
-       if (tcps == NULL) {
-               PUT_LOG_ERROR(url_protomod, LOG_CAT_L7VSD_PROTOCOL,128, "Arg(tcps) is NULL pointer.");
-               return_value = -1;
-               goto match_cldata_out;
+               goto select_dest_out;
        }
 
        /* search service that has such a service ID */
@@ -582,7 +573,7 @@ match_cldata(struct l7vs_service *srv, struct l7vs_conn *conn,
        if (url_service == NULL) {
                PUT_LOG_ERROR(url_protomod, LOG_CAT_L7VSD_PROTOCOL,129, "Could not find such service handle's url service.");
                return_value = -1;
-               goto match_cldata_out;
+               goto select_dest_out;
        }
 
        /* initialize protocol module ... clear destination list */
@@ -590,13 +581,11 @@ match_cldata(struct l7vs_service *srv, struct l7vs_conn *conn,
        if (ret != 0) {
                PUT_LOG_ERROR(url_protomod, LOG_CAT_L7VSD_PROTOCOL,130, "Could not initialize protomod.");
                return_value = -1;
-               goto match_cldata_out;
+               goto select_dest_out;
        }
 
        /* check pattern_match length */
        if (url_service->pattern_match[0] != '\0') {
-// remove log because of add new key --uri-pattern-match, --host-pattern-match)
-//             PUT_LOG_ERROR(url_protomod, LOG_CAT_L7VSD_PROTOCOL,131, "Pattern match is NULL pointer");
                /* check the size of request data */
                pattern_len = strnlen(url_service->pattern_match, PATTERN_MATCH_MAXSIZE);
                /* When '*' is included in pattern_match, number of '*' is decreased from pattern_len */ 
@@ -609,7 +598,7 @@ match_cldata(struct l7vs_service *srv, struct l7vs_conn *conn,
                if (*len < (15 + pattern_len) ) {
                        PUT_LOG_INFO(url_protomod, LOG_CAT_L7VSD_PROTOCOL,6, "Request data is too short.");
                        return_value = 1;
-                       goto match_cldata_out;
+                       goto select_dest_out;
                }
        }
        
@@ -619,7 +608,7 @@ match_cldata(struct l7vs_service *srv, struct l7vs_conn *conn,
        if (uri == NULL) {
                PUT_LOG_INFO(url_protomod, LOG_CAT_L7VSD_PROTOCOL,7, "Client message is not HTTP request.");
                return_value = 1;
-               goto match_cldata_out;
+               goto select_dest_out;
        }
        
        /* check keyword (URI/--uri-pattern-match)*/
@@ -631,7 +620,7 @@ match_cldata(struct l7vs_service *srv, struct l7vs_conn *conn,
                if ( !boost::regex_search(packet_data, url_service->uri_regex) ) {
 #endif
                        return_value = -1;
-                       goto match_cldata_out;
+                       goto select_dest_out;
                }
        }
        /* check keyword (URI/--pattern-match)*/
@@ -650,7 +639,7 @@ match_cldata(struct l7vs_service *srv, struct l7vs_conn *conn,
                if (host == NULL) {
                        PUT_LOG_INFO(url_protomod, LOG_CAT_L7VSD_PROTOCOL,8, "Could not find Host field.");
                        return_value = 1;
-                       goto match_cldata_out;
+                       goto select_dest_out;
                }
                else {  
                        next_line = http_skip_header_line(host);
@@ -668,7 +657,7 @@ match_cldata(struct l7vs_service *srv, struct l7vs_conn *conn,
                                        if ( !boost::regex_search(packet_data, url_service->host_regex) ) {
 #endif
                                                return_value = -1;
-                                               goto match_cldata_out;
+                                               goto select_dest_out;
                                        }
                                }
                                /* check keyword (HOST/--pattern-match) */
@@ -679,7 +668,7 @@ match_cldata(struct l7vs_service *srv, struct l7vs_conn *conn,
                                        *next_line = backup_char;
                                        if ( ret != 0 ) {
                                                return_value = 1;
-                                               goto match_cldata_out;
+                                               goto select_dest_out;
                                        }
                                }
                        }
@@ -687,6 +676,120 @@ match_cldata(struct l7vs_service *srv, struct l7vs_conn *conn,
                }
        }
 
+       /* finalize */
+       ret = srv->pm->finalize(srv, conn, request, *len, dest, url_service->reschedule);
+       if (ret != 0) {
+               PUT_LOG_INFO(url_protomod, LOG_CAT_L7VSD_PROTOCOL,12, "Could not finalize protomod. (Realserver decision failure)");
+               return_value = -1;
+               goto select_dest_out;
+       }
+
+select_dest_out:
+       /*-------- DEBUG LOG --------*/
+       if (url_protomod.get_log_level != NULL &&
+           LOG_LV_DEBUG == url_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
+               PUT_LOG_DEBUG(url_protomod, LOG_CAT_L7VSD_PROTOCOL,150,
+                   "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);
+       }
+       /*------ DEBUG LOG END ------*/
+
+       return return_value;
+}
+
+/*!
+ * Analyze and modify client packet
+ * @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_url_service *url_service;
+       int ret;
+       int i;
+       int asterisk_num = 0;
+       size_t pattern_len;
+       size_t uri_len;
+       char *uri, *host, pattern[PATTERN_MATCH_MAXSIZE + 2];
+       int offset_length;
+       char *x_forwarded_value;
+       char *next_line = NULL;
+       char x_forwarded_for_header[X_FORWARDED_FOR_LENGTH];
+       char backup_char;
+       int return_value = 0;
+
+       std::string packet_data;
+
+       /*-------- DEBUG LOG --------*/
+       if (url_protomod.get_log_level != NULL &&
+           LOG_LV_DEBUG == url_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
+               char srv_str[DEBUG_STR_LEN] = {0};
+               char conn_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(url_protomod, LOG_CAT_L7VSD_PROTOCOL,148,
+                   "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(url_protomod, LOG_CAT_L7VSD_PROTOCOL,123, "Arg(srv) is NULL pointer.");
+               return_value = -1;
+               goto analyze_cldata_out;
+       }
+       if (srv->pm == NULL) {
+               PUT_LOG_ERROR(url_protomod, LOG_CAT_L7VSD_PROTOCOL,124, "Arg(srv->pm) is NULL pointer.");
+               return_value = -1;
+               goto analyze_cldata_out;
+       }
+       if (request == NULL) {
+               PUT_LOG_ERROR(url_protomod, LOG_CAT_L7VSD_PROTOCOL,125, "Arg(request) is NULL pointer.");
+               return_value = -1;
+               goto analyze_cldata_out;
+       }
+       if (len == NULL) {
+               PUT_LOG_ERROR(url_protomod, LOG_CAT_L7VSD_PROTOCOL,126, "Arg(len) is NULL pointer.");
+               return_value = -1;
+               goto analyze_cldata_out;
+       }
+
+       /* search service that has such a service ID */
+       url_service = l7vs_protomod_url_search_service(srv->handle);
+
+       /*-------- DEBUG LOG --------*/
+       if (url_protomod.get_log_level != NULL &&
+           LOG_LV_DEBUG == url_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
+               char url_str[DEBUG_STR_LEN] = {0};
+               l7vs_url_service_c_str(url_str, url_service);
+               PUT_LOG_DEBUG(url_protomod, LOG_CAT_L7VSD_PROTOCOL,149, "pointer assign: url_service=&(%s)",
+                   url_str);
+       }
+       /*------ DEBUG LOG END ------*/
+
+       if (url_service == NULL) {
+               PUT_LOG_ERROR(url_protomod, LOG_CAT_L7VSD_PROTOCOL,129, "Could not find such service handle's url service.");
+               return_value = -1;
+               goto analyze_cldata_out;
+       }
+
        /* add X-Forwarded-For field */
        if (url_service->forwarded_for) {
                x_forwarded_value = http_search_header_field(request, "X-Forwarded-For");
@@ -725,22 +828,12 @@ match_cldata(struct l7vs_service *srv, struct l7vs_conn *conn,
                }
        }
 
-       *tcps = 0;
-
-       /* finalize */
-       ret = srv->pm->finalize(srv, conn, request, *len, dest, url_service->reschedule);
-       if (ret != 0) {
-               PUT_LOG_INFO(url_protomod, LOG_CAT_L7VSD_PROTOCOL,12, "Could not finalize protomod. (Realserver decision failure)");
-               return_value = -1;
-               goto match_cldata_out;
-       }
-
-match_cldata_out:
+analyze_cldata_out:
        /*-------- DEBUG LOG --------*/
        if (url_protomod.get_log_level != NULL &&
            LOG_LV_DEBUG == url_protomod.get_log_level(LOG_CAT_L7VSD_PROTOCOL)) {
                PUT_LOG_DEBUG(url_protomod, LOG_CAT_L7VSD_PROTOCOL,150,
-                   "out_function: int match_cldata(struct l7vs_service* srv, struct l7vs_conn* conn, "
+                   "out_function: int analyze_cldata(struct l7vs_service* srv, struct l7vs_conn* conn, "
                    "char* request, size_t* len, struct l7vs_dest** dest, int* tcps):return_value=%d",
                    return_value);
        }