diff options
Diffstat (limited to 'src/lib/protocols/http.c')
-rw-r--r-- | src/lib/protocols/http.c | 451 |
1 files changed, 222 insertions, 229 deletions
diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c index 2109f8ed3..f4cf31160 100644 --- a/src/lib/protocols/http.c +++ b/src/lib/protocols/http.c @@ -113,14 +113,8 @@ static int ndpi_search_http_tcp_again(struct ndpi_detection_module_struct *ndpi_ printf("=> %s()\n", __FUNCTION__); #endif - if((flow->host_server_name[0] != '\0') - && (flow->http.response_status_code != 0) - ) { - /* stop extra processing */ - if(flow->initial_binary_bytes_len) ndpi_analyze_content_signature(ndpi_struct, flow); - - flow->extra_packets_func = NULL; /* We're good now */ - return(0); + if(flow->extra_packets_func == NULL) { + return(0); /* We're good now */ } /* Possibly more processing */ @@ -287,8 +281,6 @@ static ndpi_protocol_category_t ndpi_http_check_content(struct ndpi_detection_mo } } } - - ndpi_validate_http_content(ndpi_struct, flow); } } @@ -344,42 +336,23 @@ static ndpi_protocol_category_t ndpi_http_check_content(struct ndpi_detection_mo static void ndpi_int_http_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, - u_int16_t http_protocol) { - u_int16_t master_protocol; - + u_int16_t master_protocol) { #ifdef HTTP_DEBUG printf("=> %s()\n", __FUNCTION__); #endif - master_protocol = NDPI_PROTOCOL_HTTP; - if(flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN) - master_protocol = flow->detected_protocol_stack[1]; - else if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP_CONNECT || - flow->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP_PROXY) - master_protocol = flow->detected_protocol_stack[0]; - /* Update the classification only if we don't already have master + app; for example don't change the protocols if we have already detected a sub-protocol via the (content-matched) subprotocols logic (i.e. MPEGDASH, SOAP, ....) */ - if(flow->detected_protocol_stack[1] == 0) - ndpi_set_detected_protocol(ndpi_struct, flow, http_protocol, - master_protocol, - NDPI_CONFIDENCE_DPI); + if(flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN) { + NDPI_LOG_DBG2(ndpi_struct, "Master: %d\n", master_protocol); + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_UNKNOWN, + master_protocol, NDPI_CONFIDENCE_DPI); + } flow->max_extra_packets_to_check = 8; flow->extra_packets_func = ndpi_search_http_tcp_again; - flow->http_detected = 1; - - switch(flow->detected_protocol_stack[1]) { - case NDPI_PROTOCOL_HTTP_CONNECT: - case NDPI_PROTOCOL_HTTP_PROXY: - if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP) { - flow->detected_protocol_stack[0] = flow->detected_protocol_stack[1]; - flow->detected_protocol_stack[1] = NDPI_PROTOCOL_UNKNOWN; - } - break; - } } /* ************************************************************* */ @@ -684,10 +657,12 @@ void http_process_user_agent(struct ndpi_detection_module_struct *ndpi_struct, } } - if(ndpi_user_agent_set(flow, ua_ptr, ua_ptr_len) != NULL) + if(ndpi_user_agent_set(flow, ua_ptr, ua_ptr_len) != NULL) { + ndpi_unset_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT); ndpi_check_user_agent(ndpi_struct, flow, flow->http.user_agent, ua_ptr_len); - else + } else { NDPI_LOG_DBG2(ndpi_struct, "Could not set HTTP user agent (already set?)\n"); + } NDPI_LOG_DBG2(ndpi_struct, "User Agent Type line found %.*s\n", ua_ptr_len, ua_ptr); @@ -952,10 +927,6 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ if(flow->guessed_protocol_id == NDPI_PROTOCOL_UNKNOWN) flow->guessed_protocol_id = NDPI_PROTOCOL_HTTP; - if(ndpi_get_http_method(ndpi_struct, flow) != NDPI_HTTP_METHOD_UNKNOWN) { - ndpi_int_http_add_connection(ndpi_struct, flow, flow->detected_protocol_stack[0]); - } - ndpi_check_http_header(ndpi_struct, flow); } @@ -1195,233 +1166,248 @@ static void parse_response_code(struct ndpi_detection_module_struct *ndpi_struct } } -/*************************************************************************************************/ - -static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow) { +static int is_request(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &ndpi_struct->packet; - u_int16_t filename_start; /* the filename in the request method line, e.g., "GET filename_start..."*/ - - packet->packet_lines_parsed_complete = 0; - - if(packet->http_check_content && (packet->payload_packet_len > 0)) { - ndpi_http_check_human_redeable_content(ndpi_struct, flow, packet->payload, packet->payload_packet_len); - packet->http_check_content = 0; /* One packet is enough */ - } + u_int16_t filename_start; - /* Check if we so far detected the protocol in the request or not. */ - if(flow->l4.tcp.http_stage == 0) { - /* Expected a request */ - flow->http_detected = 0; - - NDPI_LOG_DBG2(ndpi_struct, "HTTP stage %d: \n", flow->l4.tcp.http_stage); + filename_start = http_request_url_offset(ndpi_struct, flow); + /* This check is required as RTSP is pretty similiar to HTTP */ + if(filename_start > 0 && + strncasecmp((const char *)packet->payload + filename_start, + "rtsp://", ndpi_min(7, packet->payload_packet_len - filename_start)) == 0) + return 0; + return filename_start; +} - filename_start = http_request_url_offset(ndpi_struct, flow); +static int is_response(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &ndpi_struct->packet; + if(packet->payload_packet_len >= 7 && + strncasecmp((const char *)packet->payload, "HTTP/1.", 7) == 0) + return 1; + return 0; +} - if(filename_start == 0) { /* not a regular request. In the HTTP first stage, may be a truncated flow or other protocols */ - NDPI_LOG_DBG2(ndpi_struct, "Filename HTTP not found, we look for possible truncate flow..\n"); +static void process_request(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + u_int16_t filename_start) { + struct ndpi_packet_struct *packet = &ndpi_struct->packet; + u_int16_t master_protocol; - if(packet->payload_packet_len >= 7 && strncasecmp((const char *)packet->payload, "HTTP/1.", 7) == 0) { - NDPI_LOG_INFO(ndpi_struct, "found HTTP response\n"); + ndpi_parse_packet_line_info(ndpi_struct, flow); - parse_response_code(ndpi_struct, flow); + master_protocol = NDPI_PROTOCOL_HTTP; - if(flow->flow_payload) { - char *endl; - - flow->flow_payload[flow->flow_payload_len] = '\0'; - if((endl = strrchr(flow->flow_payload, '\r')) == NULL) - endl = strrchr(flow->flow_payload, '\n'); + if(packet->parsed_lines == 0 || + !(packet->line[0].len >= (9 + filename_start) && + strncasecmp((const char *)&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0)) { + NDPI_LOG_DBG2(ndpi_struct, "Request with an incomplete or invalid first line\n"); + /* Since we don't save data across different packets, we will never have + the complete url: we can't check for HTTP_PROXY */ + if(filename_start == 8 && + strncasecmp((const char *)packet->payload, "CONNECT ", 8) == 0) { + master_protocol = NDPI_PROTOCOL_HTTP_CONNECT; + } + } else { + /* First line is complete (example: "GET / HTTP/1.1"): extract url */ - if(endl != NULL) { - endl[0] = '\0'; - flow->flow_payload_len = endl - flow->flow_payload; - } - } + packet->http_url_name.ptr = &packet->payload[filename_start]; + packet->http_url_name.len = packet->line[0].len - (filename_start + 9); - ndpi_parse_packet_line_info(ndpi_struct, flow); - check_content_type_and_change_protocol(ndpi_struct, flow); - ndpi_validate_http_content(ndpi_struct, flow); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); - return; - } + packet->http_method.ptr = packet->line[0].ptr; + packet->http_method.len = filename_start - 1; - /* try to get some additional request header info even if the packet may not be HTTP */ - ndpi_parse_packet_line_info(ndpi_struct, flow); - if(packet->http_num_headers > 0) { - check_content_type_and_change_protocol(ndpi_struct, flow); - return; - } + /* Set the HTTP requested version: 0=HTTP/1.0 and 1=HTTP/1.1 */ + if(memcmp(&packet->line[0].ptr[packet->line[0].len - 1], "1", 1) == 0) + flow->http.request_version = 1; + else + flow->http.request_version = 0; - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - return; - } else { - /* This check is required as RTSP is pretty similiar to HTTP (prevent false-positives). */ - if (strncasecmp((const char *)packet->payload + filename_start, - "rtsp://", ndpi_min(7, packet->payload_packet_len - filename_start)) == 0) - { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - return; - } else { - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); - } + if(packet->http_url_name.len > 7 && + !strncasecmp((const char*) packet->http_url_name.ptr, "http://", 7)) { + master_protocol = NDPI_PROTOCOL_HTTP_PROXY; } + if(filename_start == 8 && + strncasecmp((const char *)packet->payload, "CONNECT ", 8) == 0) { + master_protocol = NDPI_PROTOCOL_HTTP_CONNECT; + } + } + ndpi_int_http_add_connection(ndpi_struct, flow, master_protocol); + check_content_type_and_change_protocol(ndpi_struct, flow); - NDPI_LOG_DBG2(ndpi_struct, - "Filename HTTP found: %d, we look for line info..\n", filename_start); - - ndpi_parse_packet_line_info(ndpi_struct, flow); + if(flow->http.user_agent == NULL || + flow->http.user_agent[0] == '\0') { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, "Empty or missing User-Agent"); + } +} - if(packet->parsed_lines <= 1) { - NDPI_LOG_DBG2(ndpi_struct, - "Found just one line, we will look further for the next packet...\n"); +static void process_response(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { - /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ - flow->l4.tcp.http_stage = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2 - return; - } + ndpi_parse_packet_line_info(ndpi_struct, flow); + parse_response_code(ndpi_struct, flow); + check_content_type_and_change_protocol(ndpi_struct, flow); - NDPI_LOG_DBG2(ndpi_struct, - "Found more than one line, we look further for the next packet...\n"); + ndpi_validate_http_content(ndpi_struct, flow); +} - if(packet->line[0].len >= (9 + filename_start) - && strncasecmp((const char *)&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) { - /* Request line complete. Ex. "GET / HTTP/1.1" */ +static void reset(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { - packet->http_url_name.ptr = &packet->payload[filename_start]; - packet->http_url_name.len = packet->line[0].len - (filename_start + 9); + NDPI_LOG_DBG2(ndpi_struct, "Reset status and risks\n"); - packet->http_method.ptr = packet->line[0].ptr; - packet->http_method.len = filename_start - 1; + /* Reset everthing in flow->http. + TODO: Could we be smarter? Probably some info don't change across + different req-res transactions... */ - // Set the HTTP requested version: 0=HTTP/1.0 and 1=HTTP/1.1 - if(memcmp(&packet->line[0].ptr[packet->line[0].len - 1], "1", 1) == 0) - flow->http.request_version = 1; - else - flow->http.request_version = 0; + flow->http.method = 0; + flow->http.request_version = 0; + flow->http.response_status_code = 0; + if(flow->http.url) { + ndpi_free(flow->http.url); + flow->http.url = NULL; + } + if(flow->http.content_type) { + ndpi_free(flow->http.content_type); + flow->http.content_type = NULL; + } + if(flow->http.request_content_type) { + ndpi_free(flow->http.request_content_type); + flow->http.request_content_type = NULL; + } + if(flow->http.user_agent) { + ndpi_free(flow->http.user_agent); + flow->http.user_agent = NULL; + } + if(flow->http.server) { + ndpi_free(flow->http.server); + flow->http.server = NULL; + } + if(flow->http.detected_os) { + ndpi_free(flow->http.detected_os); + flow->http.detected_os = NULL; + } + if(flow->http.nat_ip) { + ndpi_free(flow->http.nat_ip); + flow->http.nat_ip = NULL; + } - if((packet->http_url_name.len > 7) - && (!strncasecmp((const char*) packet->http_url_name.ptr, "http://", 7))) { - NDPI_LOG_INFO(ndpi_struct, "found HTTP_PROXY\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_HTTP_PROXY, NDPI_CONFIDENCE_DPI); - check_content_type_and_change_protocol(ndpi_struct, flow); - flow->http_detected = 1; - flow->l4.tcp.http_stage = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2 - return; - } + /* Reset flow risks. We should reset only those risks triggered by + the previous HTTP response... */ + /* TODO */ + ndpi_unset_risk(ndpi_struct, flow, NDPI_BINARY_APPLICATION_TRANSFER); + ndpi_unset_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_CONTENT); + ndpi_unset_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT); + ndpi_unset_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT); + ndpi_unset_risk(ndpi_struct, flow, NDPI_HTTP_CRAWLER_BOT); + ndpi_unset_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST); + ndpi_unset_risk(ndpi_struct, flow, NDPI_URL_POSSIBLE_RCE_INJECTION); + ndpi_unset_risk(ndpi_struct, flow, NDPI_HTTP_OBSOLETE_SERVER); + ndpi_unset_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); + ndpi_unset_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS); + ndpi_unset_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER); + ndpi_unset_risk(ndpi_struct, flow, NDPI_ERROR_CODE_DETECTED); + ndpi_unset_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET); +} - if(filename_start == 8 && (strncasecmp((const char *)packet->payload, "CONNECT ", 8) == 0)) { - NDPI_LOG_INFO(ndpi_struct, "found HTTP_CONNECT\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_HTTP_CONNECT, NDPI_CONFIDENCE_DPI); - check_content_type_and_change_protocol(ndpi_struct, flow); - flow->http_detected = 1; - flow->l4.tcp.http_stage = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2 - return; - } +static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { + struct ndpi_packet_struct *packet = &ndpi_struct->packet; + u_int16_t filename_start; + + NDPI_LOG_DBG(ndpi_struct, "http_stage %d dir %d req/res %d/%d\n", + flow->l4.tcp.http_stage, packet->packet_direction, + is_request(ndpi_struct, flow), is_response(ndpi_struct, flow)); + + if(flow->l4.tcp.http_stage == 0) { /* Start: waiting for (the beginning of) a request */ + filename_start = is_request(ndpi_struct, flow); + if(filename_start == 0) { + /* Flow starting with a response? */ + if(is_response(ndpi_struct, flow)) { + NDPI_LOG_DBG2(ndpi_struct, "Response where a request were expected\n"); + /* This is tricky. Two opposing goals: + 1) We want to correctly match request with response!! -> Skip this response + and keep looking for a request. + 2) We want to support asymmetric detection + Trade-off: + a) set HTTP as master (it is a guess; we can't know it from the reply only) + b) process the response(s) and save the metadata + c) look for a request. If we found it, reset everything (master, + classification and metadata!) */ + ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); + process_response(ndpi_struct, flow); - NDPI_LOG_DBG2(ndpi_struct, - "HTTP START Found, we will look for sub-protocols (content and host)...\n"); - - if(packet->host_line.ptr != NULL) { - /** - nDPI is pretty scrupulous about HTTP so it waits until the - HTTP response is received just to check that it conforms - with the HTTP specs. However this might be a waste of time as - in 99.99% of the cases is like that. - */ - - /* if(!flow->http_detected) */ { - u_int proto = flow->detected_protocol_stack[1] ? flow->detected_protocol_stack[1] : flow->detected_protocol_stack[0]; - - if(proto == NDPI_PROTOCOL_UNKNOWN) proto = NDPI_PROTOCOL_HTTP; - ndpi_int_http_add_connection(ndpi_struct, flow, proto); - flow->http_detected = 1; - NDPI_LOG_DBG2(ndpi_struct, - "HTTP START Found, we will look further for the response...\n"); - flow->l4.tcp.http_stage = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2 - check_content_type_and_change_protocol(ndpi_struct, flow); - } + flow->l4.tcp.http_stage = packet->packet_direction + 3; // packet_direction 0: stage 3, packet_direction 1: stage 4 return; } + /* The first pkt is neither a request nor a response -> no http */ + NDPI_LOG_DBG2(ndpi_struct, "Neither req nor response -> exclude\n"); + NDPI_EXCLUDE_PROTO(ndpi_struct, flow); + return; } + NDPI_LOG_DBG2(ndpi_struct, "Request where expected\n"); - check_content_type_and_change_protocol(ndpi_struct, flow); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - } else if((flow->l4.tcp.http_stage == 1) || (flow->l4.tcp.http_stage == 2)) { - NDPI_LOG_DBG2(ndpi_struct, "HTTP stage %u: \n", flow->l4.tcp.http_stage); - - /** - At first check, if this is for sure a response packet - (in another direction. If not, if HTTP is detected do nothing now and return, - otherwise check the second packet for the HTTP request - */ - if((flow->l4.tcp.http_stage - packet->packet_direction) == 1) { /* Expected a response package */ - NDPI_LOG_DBG2(ndpi_struct, - " SECOND PAYLOAD TRAFFIC FROM CLIENT, FIRST PACKET MIGHT HAVE BEEN HTTP...UNKNOWN TRAFFIC, HERE FOR HTTP again.. \n"); - - ndpi_parse_packet_line_info(ndpi_struct, flow); - - if(packet->parsed_lines <= 1) { - /* wait some packets in case request is split over more than 2 packets */ - if(flow->packet_counter < 5) { - NDPI_LOG_DBG2(ndpi_struct, "line still not finished, search next packet\n"); - return; - } else { - /* stop parsing here */ - NDPI_LOG_DBG2(ndpi_struct, "exclude HTTP: PACKET DOES NOT HAVE A LINE STRUCTURE\n"); - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - return; - } - } - - /* The previous pkt was a valid HTTP request and this one is in the same direction: - splitted request? Try to extract more metadata */ - if(flow->http_detected) { - check_content_type_and_change_protocol(ndpi_struct, flow); - } - - // http://www.slideshare.net/DSPIP/rtsp-analysis-wireshark - if(!flow->http_detected - && packet->line[0].len >= 9 - && strncasecmp((const char *)&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) { + process_request(ndpi_struct, flow, filename_start); - NDPI_LOG_INFO(ndpi_struct, "found HTTP\n"); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); - check_content_type_and_change_protocol(ndpi_struct, flow); + /* Wait for the response */ + flow->l4.tcp.http_stage = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2 - NDPI_LOG_DBG2(ndpi_struct, - "HTTP START Found in 2. packet, we will look further for the response....\n"); - flow->http_detected = 1; + return; + } else if(flow->l4.tcp.http_stage == 1 || flow->l4.tcp.http_stage == 2) { + /* Found a request, looking for the response */ + + if(flow->l4.tcp.http_stage - packet->packet_direction == 1) { + /* Another pkt from the same direction (probably another fragment of the request) + Keep lookng for the response */ + NDPI_LOG_DBG2(ndpi_struct, "Another piece of request\n"); + filename_start = is_request(ndpi_struct, flow); + if(filename_start > 0) { + /* Probably a new, separated request (asymmetric flow or missing pkts?). + What should we do? We definitely don't want to mix data from different + requests. The easiest (but costly) idea is to reset the state and + process it (i.e. we keep the metadata of the last request that we + have processed) */ + reset(ndpi_struct, flow); + process_request(ndpi_struct, flow, filename_start); + return; } - + ndpi_parse_packet_line_info(ndpi_struct, flow); + check_content_type_and_change_protocol(ndpi_struct, flow); return; - } + } else if(is_response(ndpi_struct, flow)) { + NDPI_LOG_DBG2(ndpi_struct, "Response where expected\n"); - /** - This is a packet in another direction. Check if we find the proper response. - We have received a response for a previously identified partial HTTP request - */ + process_response(ndpi_struct, flow); - /* response without headers - * TODO: Shouldn't it be below ndpi_parse_packet_line_info, line ~825 ? - */ - if((packet->parsed_lines == 1) && (packet->packet_direction == 1 /* server -> client */)) { - /* In Apache if you do "GET /\n\n" the response comes without any header */ - NDPI_LOG_INFO(ndpi_struct, "found HTTP. (apache)\n"); - ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); + flow->l4.tcp.http_stage = 0; + } else { + NDPI_LOG_DBG2(ndpi_struct, "The msg from the server doesn't look like a response...\n"); + /* TODO */ + } + } else if(flow->l4.tcp.http_stage == 3 || flow->l4.tcp.http_stage == 4) { + /* Found a response but we want a request */ + + if(flow->l4.tcp.http_stage - packet->packet_direction == 3) { + /* Another pkt from the same direction (probably another fragment of the response) + Keep lookng for the request */ + NDPI_LOG_DBG2(ndpi_struct, "Another piece of response\n"); + if(is_response(ndpi_struct, flow)) { + /* See the comment above about how we handle consecutive requests/responses */ + reset(ndpi_struct, flow); + process_response(ndpi_struct, flow); + return; + } + ndpi_parse_packet_line_info(ndpi_struct, flow); check_content_type_and_change_protocol(ndpi_struct, flow); return; } - parse_response_code(ndpi_struct, flow); - - /* Parse packet line and we look for the subprotocols */ - ndpi_parse_packet_line_info(ndpi_struct, flow); - check_content_type_and_change_protocol(ndpi_struct, flow); - ndpi_validate_http_content(ndpi_struct, flow); + NDPI_LOG_DBG2(ndpi_struct, "Found a request. We need to reset the state!\n"); + reset(ndpi_struct, flow); flow->l4.tcp.http_stage = 0; - return; + return ndpi_check_http_tcp(ndpi_struct, flow); } } @@ -1437,6 +1423,13 @@ static void ndpi_search_http_tcp(struct ndpi_detection_module_struct *ndpi_struc NDPI_LOG_DBG(ndpi_struct, "search HTTP\n"); ndpi_check_http_tcp(ndpi_struct, flow); + + if(flow->host_server_name[0] != '\0'&& + flow->http.response_status_code != 0) { + flow->extra_packets_func = NULL; /* We're good now */ + + if(flow->initial_binary_bytes_len) ndpi_analyze_content_signature(ndpi_struct, flow); + } } /* ********************************* */ |