diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..63b3612 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +Debug +*.o +*.d +*.so +.cproject +.project +.settings/ +SI +build*/ +src/inc +src/lib64 +cmake-build-*/ +.vscode/ +.cache/ diff --git a/test/http_decoder/test_result_json/http_6over4_single_trans.json b/benchmarks/json/http/http_6over4_single_trans.json similarity index 100% rename from test/http_decoder/test_result_json/http_6over4_single_trans.json rename to benchmarks/json/http/http_6over4_single_trans.json diff --git a/test/http_decoder/test_result_json/http_chn_encode_url.json b/benchmarks/json/http/http_chn_encode_url.json similarity index 100% rename from test/http_decoder/test_result_json/http_chn_encode_url.json rename to benchmarks/json/http/http_chn_encode_url.json diff --git a/test/http_decoder/test_result_json/http_chunked_res_gzip.json b/benchmarks/json/http/http_chunked_res_gzip.json similarity index 100% rename from test/http_decoder/test_result_json/http_chunked_res_gzip.json rename to benchmarks/json/http/http_chunked_res_gzip.json diff --git a/test/http_decoder/test_result_json/http_connect_flood.json b/benchmarks/json/http/http_connect_flood.json similarity index 100% rename from test/http_decoder/test_result_json/http_connect_flood.json rename to benchmarks/json/http/http_connect_flood.json diff --git a/test/http_decoder/test_result_json/http_get_encoded_uri.json b/benchmarks/json/http/http_get_encoded_uri.json similarity index 100% rename from test/http_decoder/test_result_json/http_get_encoded_uri.json rename to benchmarks/json/http/http_get_encoded_uri.json diff --git a/test/http_decoder/test_result_json/http_get_long_cookie.json b/benchmarks/json/http/http_get_long_cookie.json similarity index 100% rename from test/http_decoder/test_result_json/http_get_long_cookie.json rename to benchmarks/json/http/http_get_long_cookie.json diff --git a/test/http_decoder/test_result_json/http_get_malformed.json b/benchmarks/json/http/http_get_malformed.json similarity index 100% rename from test/http_decoder/test_result_json/http_get_malformed.json rename to benchmarks/json/http/http_get_malformed.json diff --git a/test/http_decoder/test_result_json/http_get_multi_trans.json b/benchmarks/json/http/http_get_multi_trans.json similarity index 100% rename from test/http_decoder/test_result_json/http_get_multi_trans.json rename to benchmarks/json/http/http_get_multi_trans.json diff --git a/test/http_decoder/test_result_json/http_get_req_pipeline.json b/benchmarks/json/http/http_get_req_pipeline.json similarity index 100% rename from test/http_decoder/test_result_json/http_get_req_pipeline.json rename to benchmarks/json/http/http_get_req_pipeline.json diff --git a/test/http_decoder/test_result_json/http_get_single_trans.json b/benchmarks/json/http/http_get_single_trans.json similarity index 100% rename from test/http_decoder/test_result_json/http_get_single_trans.json rename to benchmarks/json/http/http_get_single_trans.json diff --git a/test/http_decoder/test_result_json/http_gzip_out_of_order.json b/benchmarks/json/http/http_gzip_out_of_order.json similarity index 100% rename from test/http_decoder/test_result_json/http_gzip_out_of_order.json rename to benchmarks/json/http/http_gzip_out_of_order.json diff --git a/test/http_decoder/test_result_json/http_hdr_truncated_after_kv.json b/benchmarks/json/http/http_hdr_truncated_after_kv.json similarity index 100% rename from test/http_decoder/test_result_json/http_hdr_truncated_after_kv.json rename to benchmarks/json/http/http_hdr_truncated_after_kv.json diff --git a/test/http_decoder/test_result_json/http_hdr_truncated_in_kv.json b/benchmarks/json/http/http_hdr_truncated_in_kv.json similarity index 100% rename from test/http_decoder/test_result_json/http_hdr_truncated_in_kv.json rename to benchmarks/json/http/http_hdr_truncated_in_kv.json diff --git a/test/http_decoder/test_result_json/http_hdr_value_empty.json b/benchmarks/json/http/http_hdr_value_empty.json similarity index 100% rename from test/http_decoder/test_result_json/http_hdr_value_empty.json rename to benchmarks/json/http/http_hdr_value_empty.json diff --git a/test/http_decoder/test_result_json/http_hdrs_exceed_maximum.json b/benchmarks/json/http/http_hdrs_exceed_maximum.json similarity index 100% rename from test/http_decoder/test_result_json/http_hdrs_exceed_maximum.json rename to benchmarks/json/http/http_hdrs_exceed_maximum.json diff --git a/test/http_decoder/test_result_json/http_inner_tunnel_for_http.json b/benchmarks/json/http/http_inner_tunnel_for_http.json similarity index 100% rename from test/http_decoder/test_result_json/http_inner_tunnel_for_http.json rename to benchmarks/json/http/http_inner_tunnel_for_http.json diff --git a/test/http_decoder/test_result_json/http_inner_tunnel_for_pop3.json b/benchmarks/json/http/http_inner_tunnel_for_pop3.json similarity index 100% rename from test/http_decoder/test_result_json/http_inner_tunnel_for_pop3.json rename to benchmarks/json/http/http_inner_tunnel_for_pop3.json diff --git a/test/http_decoder/test_result_json/http_msg_type_state.json b/benchmarks/json/http/http_msg_type_state.json similarity index 100% rename from test/http_decoder/test_result_json/http_msg_type_state.json rename to benchmarks/json/http/http_msg_type_state.json diff --git a/test/http_decoder/test_result_json/http_msg_type_state_c2s.json b/benchmarks/json/http/http_msg_type_state_c2s.json similarity index 100% rename from test/http_decoder/test_result_json/http_msg_type_state_c2s.json rename to benchmarks/json/http/http_msg_type_state_c2s.json diff --git a/test/http_decoder/test_result_json/http_msg_type_state_exception_c2s.json b/benchmarks/json/http/http_msg_type_state_exception_c2s.json similarity index 100% rename from test/http_decoder/test_result_json/http_msg_type_state_exception_c2s.json rename to benchmarks/json/http/http_msg_type_state_exception_c2s.json diff --git a/test/http_decoder/test_result_json/http_msg_type_state_exception_s2c.json b/benchmarks/json/http/http_msg_type_state_exception_s2c.json similarity index 100% rename from test/http_decoder/test_result_json/http_msg_type_state_exception_s2c.json rename to benchmarks/json/http/http_msg_type_state_exception_s2c.json diff --git a/test/http_decoder/test_result_json/http_msg_type_state_pipeline.json b/benchmarks/json/http/http_msg_type_state_pipeline.json similarity index 100% rename from test/http_decoder/test_result_json/http_msg_type_state_pipeline.json rename to benchmarks/json/http/http_msg_type_state_pipeline.json diff --git a/test/http_decoder/test_result_json/http_msg_type_state_s2c.json b/benchmarks/json/http/http_msg_type_state_s2c.json similarity index 100% rename from test/http_decoder/test_result_json/http_msg_type_state_s2c.json rename to benchmarks/json/http/http_msg_type_state_s2c.json diff --git a/test/http_decoder/test_result_json/http_msg_type_state_tunnel.json b/benchmarks/json/http/http_msg_type_state_tunnel.json similarity index 100% rename from test/http_decoder/test_result_json/http_msg_type_state_tunnel.json rename to benchmarks/json/http/http_msg_type_state_tunnel.json diff --git a/test/http_decoder/test_result_json/http_msg_type_state_tunnel_c2s.json b/benchmarks/json/http/http_msg_type_state_tunnel_c2s.json similarity index 100% rename from test/http_decoder/test_result_json/http_msg_type_state_tunnel_c2s.json rename to benchmarks/json/http/http_msg_type_state_tunnel_c2s.json diff --git a/test/http_decoder/test_result_json/http_msg_type_state_tunnel_s2c.json b/benchmarks/json/http/http_msg_type_state_tunnel_s2c.json similarity index 100% rename from test/http_decoder/test_result_json/http_msg_type_state_tunnel_s2c.json rename to benchmarks/json/http/http_msg_type_state_tunnel_s2c.json diff --git a/test/http_decoder/test_result_json/http_multi_parse_error.json b/benchmarks/json/http/http_multi_parse_error.json similarity index 100% rename from test/http_decoder/test_result_json/http_multi_parse_error.json rename to benchmarks/json/http/http_multi_parse_error.json diff --git a/test/http_decoder/test_result_json/http_no_content_length.json b/benchmarks/json/http/http_no_content_length.json similarity index 100% rename from test/http_decoder/test_result_json/http_no_content_length.json rename to benchmarks/json/http/http_no_content_length.json diff --git a/test/http_decoder/test_result_json/http_out_of_order.json b/benchmarks/json/http/http_out_of_order.json similarity index 100% rename from test/http_decoder/test_result_json/http_out_of_order.json rename to benchmarks/json/http/http_out_of_order.json diff --git a/test/http_decoder/test_result_json/http_over_pppoe.json b/benchmarks/json/http/http_over_pppoe.json similarity index 100% rename from test/http_decoder/test_result_json/http_over_pppoe.json rename to benchmarks/json/http/http_over_pppoe.json diff --git a/test/http_decoder/test_result_json/http_over_tcp_keepalive.json b/benchmarks/json/http/http_over_tcp_keepalive.json similarity index 100% rename from test/http_decoder/test_result_json/http_over_tcp_keepalive.json rename to benchmarks/json/http/http_over_tcp_keepalive.json diff --git a/test/http_decoder/test_result_json/http_over_tls.json b/benchmarks/json/http/http_over_tls.json similarity index 100% rename from test/http_decoder/test_result_json/http_over_tls.json rename to benchmarks/json/http/http_over_tls.json diff --git a/test/http_decoder/test_result_json/http_post_multipart_form_data.json b/benchmarks/json/http/http_post_multipart_form_data.json similarity index 100% rename from test/http_decoder/test_result_json/http_post_multipart_form_data.json rename to benchmarks/json/http/http_post_multipart_form_data.json diff --git a/test/http_decoder/test_result_json/http_post_single_trans.json b/benchmarks/json/http/http_post_single_trans.json similarity index 100% rename from test/http_decoder/test_result_json/http_post_single_trans.json rename to benchmarks/json/http/http_post_single_trans.json diff --git a/test/http_decoder/test_result_json/http_req_1byte_sliding_window.json b/benchmarks/json/http/http_req_1byte_sliding_window.json similarity index 100% rename from test/http_decoder/test_result_json/http_req_1byte_sliding_window.json rename to benchmarks/json/http/http_req_1byte_sliding_window.json diff --git a/test/http_decoder/test_result_json/http_res_1byte_sliding_window.json b/benchmarks/json/http/http_res_1byte_sliding_window.json similarity index 100% rename from test/http_decoder/test_result_json/http_res_1byte_sliding_window.json rename to benchmarks/json/http/http_res_1byte_sliding_window.json diff --git a/test/http_decoder/test_result_json/http_res_gzip.json b/benchmarks/json/http/http_res_gzip.json similarity index 100% rename from test/http_decoder/test_result_json/http_res_gzip.json rename to benchmarks/json/http/http_res_gzip.json diff --git a/test/http_decoder/test_result_json/http_trans_pipeline.json b/benchmarks/json/http/http_trans_pipeline.json similarity index 100% rename from test/http_decoder/test_result_json/http_trans_pipeline.json rename to benchmarks/json/http/http_trans_pipeline.json diff --git a/test/http_decoder/test_result_json/http_tunnel_for_http.json b/benchmarks/json/http/http_tunnel_for_http.json similarity index 100% rename from test/http_decoder/test_result_json/http_tunnel_for_http.json rename to benchmarks/json/http/http_tunnel_for_http.json diff --git a/test/http_decoder/test_result_json/http_tunnel_for_http_c2s.json b/benchmarks/json/http/http_tunnel_for_http_c2s.json similarity index 100% rename from test/http_decoder/test_result_json/http_tunnel_for_http_c2s.json rename to benchmarks/json/http/http_tunnel_for_http_c2s.json diff --git a/test/http_decoder/test_result_json/http_tunnel_for_http_s2c.json b/benchmarks/json/http/http_tunnel_for_http_s2c.json similarity index 100% rename from test/http_decoder/test_result_json/http_tunnel_for_http_s2c.json rename to benchmarks/json/http/http_tunnel_for_http_s2c.json diff --git a/test/http_decoder/test_result_json/http_tunnel_for_pop3.json b/benchmarks/json/http/http_tunnel_for_pop3.json similarity index 100% rename from test/http_decoder/test_result_json/http_tunnel_for_pop3.json rename to benchmarks/json/http/http_tunnel_for_pop3.json diff --git a/test/http_decoder/test_result_json/http_tunnel_s2c_only_hdr.json b/benchmarks/json/http/http_tunnel_s2c_only_hdr.json similarity index 100% rename from test/http_decoder/test_result_json/http_tunnel_s2c_only_hdr.json rename to benchmarks/json/http/http_tunnel_s2c_only_hdr.json diff --git a/test/http_decoder/test_result_json/http_upgrade_http2.json b/benchmarks/json/http/http_upgrade_http2.json similarity index 100% rename from test/http_decoder/test_result_json/http_upgrade_http2.json rename to benchmarks/json/http/http_upgrade_http2.json diff --git a/test/http_decoder/test_result_json/http_upgrade_websocket.json b/benchmarks/json/http/http_upgrade_websocket.json similarity index 100% rename from test/http_decoder/test_result_json/http_upgrade_websocket.json rename to benchmarks/json/http/http_upgrade_websocket.json diff --git a/test/http_decoder/test_result_json/http_url_test_with_host.json b/benchmarks/json/http/http_url_test_with_host.json similarity index 100% rename from test/http_decoder/test_result_json/http_url_test_with_host.json rename to benchmarks/json/http/http_url_test_with_host.json diff --git a/test/http_decoder/test_result_json/http_url_test_without_host.json b/benchmarks/json/http/http_url_test_without_host.json similarity index 100% rename from test/http_decoder/test_result_json/http_url_test_without_host.json rename to benchmarks/json/http/http_url_test_without_host.json diff --git a/test/http_decoder/test_result_json/http_url_test_without_host_v6.json b/benchmarks/json/http/http_url_test_without_host_v6.json similarity index 100% rename from test/http_decoder/test_result_json/http_url_test_without_host_v6.json rename to benchmarks/json/http/http_url_test_without_host_v6.json diff --git a/test/http_decoder/test_result_json/http_zlib_deadlock.json b/benchmarks/json/http/http_zlib_deadlock.json similarity index 100% rename from test/http_decoder/test_result_json/http_zlib_deadlock.json rename to benchmarks/json/http/http_zlib_deadlock.json diff --git a/test/http_decoder/test_result_json/non_http.json b/benchmarks/json/http/non_http.json similarity index 100% rename from test/http_decoder/test_result_json/non_http.json rename to benchmarks/json/http/non_http.json diff --git a/test/http_decoder/http_pcap/http_6over4_single_trans.pcap b/benchmarks/pcap/http/http_6over4_single_trans.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_6over4_single_trans.pcap rename to benchmarks/pcap/http/http_6over4_single_trans.pcap diff --git a/test/http_decoder/http_pcap/http_chn_encode_url.pcap b/benchmarks/pcap/http/http_chn_encode_url.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_chn_encode_url.pcap rename to benchmarks/pcap/http/http_chn_encode_url.pcap diff --git a/test/http_decoder/http_pcap/http_chunked_res_gzip.pcap b/benchmarks/pcap/http/http_chunked_res_gzip.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_chunked_res_gzip.pcap rename to benchmarks/pcap/http/http_chunked_res_gzip.pcap diff --git a/test/http_decoder/http_pcap/http_connect_flood.pcap b/benchmarks/pcap/http/http_connect_flood.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_connect_flood.pcap rename to benchmarks/pcap/http/http_connect_flood.pcap diff --git a/test/http_decoder/http_pcap/http_error.pcap b/benchmarks/pcap/http/http_error.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_error.pcap rename to benchmarks/pcap/http/http_error.pcap diff --git a/test/http_decoder/http_pcap/http_fin.pcap b/benchmarks/pcap/http/http_fin.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_fin.pcap rename to benchmarks/pcap/http/http_fin.pcap diff --git a/test/http_decoder/http_pcap/http_get_encoded_uri.pcap b/benchmarks/pcap/http/http_get_encoded_uri.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_get_encoded_uri.pcap rename to benchmarks/pcap/http/http_get_encoded_uri.pcap diff --git a/test/http_decoder/http_pcap/http_get_long_cookie.pcap b/benchmarks/pcap/http/http_get_long_cookie.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_get_long_cookie.pcap rename to benchmarks/pcap/http/http_get_long_cookie.pcap diff --git a/test/http_decoder/http_pcap/http_get_malformed.pcap b/benchmarks/pcap/http/http_get_malformed.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_get_malformed.pcap rename to benchmarks/pcap/http/http_get_malformed.pcap diff --git a/test/http_decoder/http_pcap/http_get_multi_trans.pcap b/benchmarks/pcap/http/http_get_multi_trans.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_get_multi_trans.pcap rename to benchmarks/pcap/http/http_get_multi_trans.pcap diff --git a/test/http_decoder/http_pcap/http_get_req_pipeline.pcap b/benchmarks/pcap/http/http_get_req_pipeline.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_get_req_pipeline.pcap rename to benchmarks/pcap/http/http_get_req_pipeline.pcap diff --git a/test/http_decoder/http_pcap/http_get_single_trans.pcap b/benchmarks/pcap/http/http_get_single_trans.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_get_single_trans.pcap rename to benchmarks/pcap/http/http_get_single_trans.pcap diff --git a/test/http_decoder/http_pcap/http_gzip_out_of_order.pcap b/benchmarks/pcap/http/http_gzip_out_of_order.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_gzip_out_of_order.pcap rename to benchmarks/pcap/http/http_gzip_out_of_order.pcap diff --git a/test/http_decoder/http_pcap/http_hdr_truncated_after_kv.pcap b/benchmarks/pcap/http/http_hdr_truncated_after_kv.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_hdr_truncated_after_kv.pcap rename to benchmarks/pcap/http/http_hdr_truncated_after_kv.pcap diff --git a/test/http_decoder/http_pcap/http_hdr_truncated_in_kv.pcap b/benchmarks/pcap/http/http_hdr_truncated_in_kv.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_hdr_truncated_in_kv.pcap rename to benchmarks/pcap/http/http_hdr_truncated_in_kv.pcap diff --git a/test/http_decoder/http_pcap/http_hdr_value_empty.pcap b/benchmarks/pcap/http/http_hdr_value_empty.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_hdr_value_empty.pcap rename to benchmarks/pcap/http/http_hdr_value_empty.pcap diff --git a/test/http_decoder/http_pcap/http_hdrs_exceed_maximum.pcap b/benchmarks/pcap/http/http_hdrs_exceed_maximum.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_hdrs_exceed_maximum.pcap rename to benchmarks/pcap/http/http_hdrs_exceed_maximum.pcap diff --git a/test/http_decoder/http_pcap/http_multi_parse_error.pcap b/benchmarks/pcap/http/http_multi_parse_error.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_multi_parse_error.pcap rename to benchmarks/pcap/http/http_multi_parse_error.pcap diff --git a/test/http_decoder/http_pcap/http_no_content_length.pcap b/benchmarks/pcap/http/http_no_content_length.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_no_content_length.pcap rename to benchmarks/pcap/http/http_no_content_length.pcap diff --git a/test/http_decoder/http_pcap/http_out_of_order.pcap b/benchmarks/pcap/http/http_out_of_order.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_out_of_order.pcap rename to benchmarks/pcap/http/http_out_of_order.pcap diff --git a/test/http_decoder/http_pcap/http_over_pppoe.pcap b/benchmarks/pcap/http/http_over_pppoe.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_over_pppoe.pcap rename to benchmarks/pcap/http/http_over_pppoe.pcap diff --git a/test/http_decoder/http_pcap/http_over_tcp_keepalive.pcap b/benchmarks/pcap/http/http_over_tcp_keepalive.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_over_tcp_keepalive.pcap rename to benchmarks/pcap/http/http_over_tcp_keepalive.pcap diff --git a/test/http_decoder/http_pcap/http_over_tls.pcap b/benchmarks/pcap/http/http_over_tls.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_over_tls.pcap rename to benchmarks/pcap/http/http_over_tls.pcap diff --git a/test/http_decoder/http_pcap/http_pipeline_C2S.pcap b/benchmarks/pcap/http/http_pipeline_C2S.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_pipeline_C2S.pcap rename to benchmarks/pcap/http/http_pipeline_C2S.pcap diff --git a/test/http_decoder/http_pcap/http_pipeline_S2C.pcap b/benchmarks/pcap/http/http_pipeline_S2C.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_pipeline_S2C.pcap rename to benchmarks/pcap/http/http_pipeline_S2C.pcap diff --git a/test/http_decoder/http_pcap/http_post.pcap b/benchmarks/pcap/http/http_post.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_post.pcap rename to benchmarks/pcap/http/http_post.pcap diff --git a/test/http_decoder/http_pcap/http_post_c2s.pcap b/benchmarks/pcap/http/http_post_c2s.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_post_c2s.pcap rename to benchmarks/pcap/http/http_post_c2s.pcap diff --git a/test/http_decoder/http_pcap/http_post_multipart_form_data.pcap b/benchmarks/pcap/http/http_post_multipart_form_data.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_post_multipart_form_data.pcap rename to benchmarks/pcap/http/http_post_multipart_form_data.pcap diff --git a/test/http_decoder/http_pcap/http_post_s2c.pcap b/benchmarks/pcap/http/http_post_s2c.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_post_s2c.pcap rename to benchmarks/pcap/http/http_post_s2c.pcap diff --git a/test/http_decoder/http_pcap/http_post_single_trans.pcap b/benchmarks/pcap/http/http_post_single_trans.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_post_single_trans.pcap rename to benchmarks/pcap/http/http_post_single_trans.pcap diff --git a/test/http_decoder/http_pcap/http_req_1byte_sliding_window.pcap b/benchmarks/pcap/http/http_req_1byte_sliding_window.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_req_1byte_sliding_window.pcap rename to benchmarks/pcap/http/http_req_1byte_sliding_window.pcap diff --git a/test/http_decoder/http_pcap/http_res_1byte_sliding_window.pcap b/benchmarks/pcap/http/http_res_1byte_sliding_window.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_res_1byte_sliding_window.pcap rename to benchmarks/pcap/http/http_res_1byte_sliding_window.pcap diff --git a/test/http_decoder/http_pcap/http_res_gzip.pcap b/benchmarks/pcap/http/http_res_gzip.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_res_gzip.pcap rename to benchmarks/pcap/http/http_res_gzip.pcap diff --git a/test/http_decoder/http_pcap/http_session_exception_c2s.pcap b/benchmarks/pcap/http/http_session_exception_c2s.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_session_exception_c2s.pcap rename to benchmarks/pcap/http/http_session_exception_c2s.pcap diff --git a/test/http_decoder/http_pcap/http_session_exception_s2c.pcap b/benchmarks/pcap/http/http_session_exception_s2c.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_session_exception_s2c.pcap rename to benchmarks/pcap/http/http_session_exception_s2c.pcap diff --git a/test/http_decoder/http_pcap/http_trans_pipeline.pcap b/benchmarks/pcap/http/http_trans_pipeline.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_trans_pipeline.pcap rename to benchmarks/pcap/http/http_trans_pipeline.pcap diff --git a/test/http_decoder/http_pcap/http_tunnel_for_http.pcap b/benchmarks/pcap/http/http_tunnel_for_http.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_tunnel_for_http.pcap rename to benchmarks/pcap/http/http_tunnel_for_http.pcap diff --git a/test/http_decoder/http_pcap/http_tunnel_for_http_C2S.pcap b/benchmarks/pcap/http/http_tunnel_for_http_C2S.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_tunnel_for_http_C2S.pcap rename to benchmarks/pcap/http/http_tunnel_for_http_C2S.pcap diff --git a/test/http_decoder/http_pcap/http_tunnel_for_http_S2C.pcap b/benchmarks/pcap/http/http_tunnel_for_http_S2C.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_tunnel_for_http_S2C.pcap rename to benchmarks/pcap/http/http_tunnel_for_http_S2C.pcap diff --git a/test/http_decoder/http_pcap/http_tunnel_for_pop3.pcap b/benchmarks/pcap/http/http_tunnel_for_pop3.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_tunnel_for_pop3.pcap rename to benchmarks/pcap/http/http_tunnel_for_pop3.pcap diff --git a/test/http_decoder/http_pcap/http_tunnel_s2c_only_hdr.pcap b/benchmarks/pcap/http/http_tunnel_s2c_only_hdr.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_tunnel_s2c_only_hdr.pcap rename to benchmarks/pcap/http/http_tunnel_s2c_only_hdr.pcap diff --git a/test/http_decoder/http_pcap/http_upgrade_http2.pcap b/benchmarks/pcap/http/http_upgrade_http2.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_upgrade_http2.pcap rename to benchmarks/pcap/http/http_upgrade_http2.pcap diff --git a/test/http_decoder/http_pcap/http_upgrade_websocket.pcap b/benchmarks/pcap/http/http_upgrade_websocket.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_upgrade_websocket.pcap rename to benchmarks/pcap/http/http_upgrade_websocket.pcap diff --git a/test/http_decoder/http_pcap/http_url_test_with_host.pcap b/benchmarks/pcap/http/http_url_test_with_host.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_url_test_with_host.pcap rename to benchmarks/pcap/http/http_url_test_with_host.pcap diff --git a/test/http_decoder/http_pcap/http_url_test_without_host.pcap b/benchmarks/pcap/http/http_url_test_without_host.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_url_test_without_host.pcap rename to benchmarks/pcap/http/http_url_test_without_host.pcap diff --git a/test/http_decoder/http_pcap/http_url_test_without_host_v6.pcap b/benchmarks/pcap/http/http_url_test_without_host_v6.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_url_test_without_host_v6.pcap rename to benchmarks/pcap/http/http_url_test_without_host_v6.pcap diff --git a/test/http_decoder/http_pcap/http_whitespace_before_header.pcap b/benchmarks/pcap/http/http_whitespace_before_header.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_whitespace_before_header.pcap rename to benchmarks/pcap/http/http_whitespace_before_header.pcap diff --git a/test/http_decoder/http_pcap/http_zlib_deadlock.pcap b/benchmarks/pcap/http/http_zlib_deadlock.pcap similarity index 100% rename from test/http_decoder/http_pcap/http_zlib_deadlock.pcap rename to benchmarks/pcap/http/http_zlib_deadlock.pcap diff --git a/test/http_decoder/http_pcap/non_http.pcap b/benchmarks/pcap/http/non_http.pcap similarity index 100% rename from test/http_decoder/http_pcap/non_http.pcap rename to benchmarks/pcap/http/non_http.pcap diff --git a/decoders/http/CMakeLists.txt b/decoders/http/CMakeLists.txt index 7e49755..9a278d2 100644 --- a/decoders/http/CMakeLists.txt +++ b/decoders/http/CMakeLists.txt @@ -1,14 +1,18 @@ add_definitions(-fPIC) +include_directories(${CMAKE_BINARY_DIR}/vendor/llhttp/include) +include_directories(${CMAKE_BINARY_DIR}/vendor/brotli/include) +include_directories(${CMAKE_SOURCE_DIR}/deps) -set(HTTP_SRC ${DEPS_SRC} http_decoder.cpp http_decoder_utils.cpp http_decoder_half.cpp +set(HTTP_SRC http_decoder.cpp http_decoder_utils.cpp http_decoder_half.cpp http_decoder_table.cpp http_decoder_string.cpp http_content_decompress.cpp http_decoder_result_queue.cpp http_decoder_stat.cpp http_decoder_tunnel.cpp) -add_library(http_decoder STATIC ${HTTP_SRC}) -set_target_properties(http_decoder PROPERTIES LINK_FLAGS "-Wl,--version-script=${PROJECT_SOURCE_DIR}/src/version.map") -target_include_directories(http_decoder PUBLIC ${CMAKE_SOURCE_DIR}/deps/) -target_link_libraries(http_decoder z llhttp-static fieldstat4) -target_link_libraries(http_decoder brotli-dec-static brotli-common-static ) -set_target_properties(http_decoder PROPERTIES PREFIX "") +add_library(http STATIC ${HTTP_SRC}) +add_library(http_dyn SHARED ${HTTP_SRC}) +set_target_properties(http PROPERTIES LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/version.map") +target_include_directories(http PUBLIC ${CMAKE_SOURCE_DIR}/deps/) +target_link_libraries(http z llhttp-static fieldstat4 brotli-dec-static brotli-common-static nmx_pool toml) +set_target_properties(http PROPERTIES PREFIX "") -#install(TARGETS http_decoder LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/plugin/${lib_name} COMPONENT LIBRARIES) \ No newline at end of file +set_target_properties(http_dyn PROPERTIES PREFIX "") +target_link_libraries(http_dyn z llhttp-static fieldstat4 brotli-dec-static brotli-common-static nmx_pool toml) \ No newline at end of file diff --git a/decoders/http/http_content_decompress.cpp b/decoders/http/http_content_decompress.cpp index 3b71a40..cb90811 100644 --- a/decoders/http/http_content_decompress.cpp +++ b/decoders/http/http_content_decompress.cpp @@ -1,21 +1,13 @@ -/* -********************************************************************************************** -* File: http_content_decompress.c -* Description: -* Authors: LuWenPeng -* Date: 2022-10-31 -* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved. -*********************************************************************************************** -*/ #include #include #include #include -#include "http_decoder_inc.h" +#include "http_decoder_private.h" #define HTTP_DECOMPRESS_BUFFER_SIZE (4096) -struct http_content_decompress { +struct http_content_decompress +{ enum http_content_encoding encoding; z_stream *z_stream_ptr; BrotliDecoderState *br_state; @@ -23,38 +15,41 @@ struct http_content_decompress { size_t buffer_size; }; -enum http_content_encoding -http_content_encoding_str2int(const char *content_encoding) +enum http_content_encoding http_content_encoding_str2int(const char *content_encoding) { - if (strcasestr(content_encoding, "gzip") != NULL) { + if (strcasestr(content_encoding, "gzip") != NULL) + { return HTTP_CONTENT_ENCODING_GZIP; } - if (strcasestr(content_encoding, "deflate") != NULL) { + if (strcasestr(content_encoding, "deflate") != NULL) + { return HTTP_CONTENT_ENCODING_DEFLATE; } - if (strcasestr(content_encoding, "br") != NULL) { + if (strcasestr(content_encoding, "br") != NULL) + { return HTTP_CONTENT_ENCODING_BR; } return HTTP_CONTENT_ENCODING_NONE; } -const char * -http_content_encoding_int2str(enum http_content_encoding content_encoding) +const char *http_content_encoding_int2str(enum http_content_encoding content_encoding) { - if (content_encoding == HTTP_CONTENT_ENCODING_GZIP) { + if (content_encoding == HTTP_CONTENT_ENCODING_GZIP) + { return "gzip"; } - if (content_encoding == HTTP_CONTENT_ENCODING_DEFLATE) { + if (content_encoding == HTTP_CONTENT_ENCODING_DEFLATE) + { return "deflate"; } - if (content_encoding == HTTP_CONTENT_ENCODING_BR) { + if (content_encoding == HTTP_CONTENT_ENCODING_BR) + { return "br"; } return "unknown"; } -struct http_content_decompress * -http_content_decompress_create(enum http_content_encoding encoding) +struct http_content_decompress *http_content_decompress_create(enum http_content_encoding encoding) { struct http_content_decompress *decompress = CALLOC(struct http_content_decompress, 1); @@ -64,8 +59,8 @@ http_content_decompress_create(enum http_content_encoding encoding) decompress->z_stream_ptr = NULL; decompress->br_state = NULL; - if (encoding == HTTP_CONTENT_ENCODING_GZIP - || encoding == HTTP_CONTENT_ENCODING_DEFLATE) { + if (encoding == HTTP_CONTENT_ENCODING_GZIP || encoding == HTTP_CONTENT_ENCODING_DEFLATE) + { decompress->z_stream_ptr = CALLOC(z_stream, 1); assert(decompress->z_stream_ptr); @@ -75,22 +70,27 @@ http_content_decompress_create(enum http_content_encoding encoding) decompress->z_stream_ptr->avail_in = 0; decompress->z_stream_ptr->next_in = Z_NULL; - if (encoding == HTTP_CONTENT_ENCODING_GZIP) { - if (inflateInit2(decompress->z_stream_ptr, MAX_WBITS + 16) - != Z_OK) { + if (encoding == HTTP_CONTENT_ENCODING_GZIP) + { + if (inflateInit2(decompress->z_stream_ptr, MAX_WBITS + 16) != Z_OK) + { goto error; } } - if (encoding == HTTP_CONTENT_ENCODING_DEFLATE) { - if (inflateInit2(decompress->z_stream_ptr, -MAX_WBITS) != Z_OK) { + if (encoding == HTTP_CONTENT_ENCODING_DEFLATE) + { + if (inflateInit2(decompress->z_stream_ptr, -MAX_WBITS) != Z_OK) + { goto error; } } } - if (encoding == HTTP_CONTENT_ENCODING_BR) { + if (encoding == HTTP_CONTENT_ENCODING_BR) + { decompress->br_state = BrotliDecoderCreateInstance(NULL, NULL, NULL); - if (decompress->br_state == NULL) { + if (decompress->br_state == NULL) + { goto error; } } @@ -103,14 +103,17 @@ error: void http_content_decompress_destroy(struct http_content_decompress *decompress) { - if (NULL == decompress) { + if (NULL == decompress) + { return; } - if (decompress->z_stream_ptr != NULL) { + if (decompress->z_stream_ptr != NULL) + { inflateEnd(decompress->z_stream_ptr); FREE(decompress->z_stream_ptr); } - if (decompress->br_state) { + if (decompress->br_state) + { BrotliDecoderDestroyInstance(decompress->br_state); decompress->br_state = NULL; } @@ -118,10 +121,9 @@ void http_content_decompress_destroy(struct http_content_decompress *decompress) FREE(decompress); } -static int -http_content_decompress_write_zlib(struct http_content_decompress *decompress, - const char *indata, size_t indata_len, - char **outdata, size_t *outdata_len) +static int http_content_decompress_write_zlib(struct http_content_decompress *decompress, + const char *indata, size_t indata_len, + char **outdata, size_t *outdata_len) { z_stream *z_stream_ptr = decompress->z_stream_ptr; z_stream_ptr->avail_in = (unsigned int)indata_len; @@ -132,35 +134,40 @@ http_content_decompress_write_zlib(struct http_content_decompress *decompress, *outdata = NULL; *outdata_len = 0; - do { + do + { int ret = inflate(z_stream_ptr, Z_NO_FLUSH); - if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT - || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) { + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) + { (void)inflateEnd(z_stream_ptr); return -1; } size_t have = decompress->buffer_size - z_stream_ptr->avail_out; - if (have > 0) { - if (0 == z_stream_ptr->avail_out) { - fprintf(stderr, "realloc outbuffer,before: %zu bytes, after :%zu B\n", decompress->buffer_size , decompress->buffer_size + have); ; + if (have > 0) + { + if (0 == z_stream_ptr->avail_out) + { decompress->buffer_size += have; decompress->buffer = REALLOC(char, decompress->buffer, decompress->buffer_size); *outdata = decompress->buffer; *outdata_len = *outdata_len + have; - // http_decoder_log(DEBUG, "%s realloc outbuffer %zu bytes", - // http_content_encoding_int2str(decompress->encoding), + // http_decoder_log(DEBUG, "%s realloc outbuffer %zu bytes", + // http_content_encoding_int2str(decompress->encoding), // decompress->buffer_size); z_stream_ptr->avail_out = have; - z_stream_ptr->next_out = (unsigned char *)decompress->buffer + + z_stream_ptr->next_out = (unsigned char *)decompress->buffer + (decompress->buffer_size - have); - } else { + } + else + { *outdata = decompress->buffer; *outdata_len = have; } } - if(Z_STREAM_END == ret){ + if (Z_STREAM_END == ret) + { break; } } while (z_stream_ptr->avail_in != 0); @@ -169,10 +176,9 @@ http_content_decompress_write_zlib(struct http_content_decompress *decompress, return 0; } -static int -http_content_decompress_write_br(struct http_content_decompress *decompress, - const char *indata, size_t indata_len, - char **outdata, size_t *outdata_len) +static int http_content_decompress_write_br(struct http_content_decompress *decompress, + const char *indata, size_t indata_len, + char **outdata, size_t *outdata_len) { size_t available_in = indata_len; const unsigned char *next_in = (const unsigned char *)indata; @@ -182,12 +188,15 @@ http_content_decompress_write_br(struct http_content_decompress *decompress, *outdata = NULL; *outdata_len = 0; - for (;;) { - int ret = BrotliDecoderDecompressStream(decompress->br_state, &available_in, - &next_in, &available_out, &next_out, 0); + for (;;) + { + int ret = BrotliDecoderDecompressStream(decompress->br_state, &available_in, + &next_in, &available_out, &next_out, 0); size_t have = decompress->buffer_size - available_out; - if (have > 0) { - if (0 == available_out) { + if (have > 0) + { + if (0 == available_out) + { decompress->buffer_size += have; decompress->buffer = REALLOC(char, decompress->buffer, decompress->buffer_size); @@ -196,24 +205,28 @@ http_content_decompress_write_br(struct http_content_decompress *decompress, available_out = have; next_out = (unsigned char *)decompress->buffer + (decompress->buffer_size - have); - } else { + } + else + { *outdata = decompress->buffer; *outdata_len = have; } } if (ret == BROTLI_DECODER_RESULT_SUCCESS || - ret == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) { - decompress->buffer =NULL; - decompress->buffer_size = 0; + ret == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) + { + decompress->buffer = NULL; + decompress->buffer_size = 0; return 0; } - if (ret == BROTLI_DECODER_RESULT_ERROR) { - //BrotliDecoderErrorCode errcode = - BrotliDecoderGetErrorCode(decompress->br_state); - *outdata = NULL; - *outdata_len = 0; + if (ret == BROTLI_DECODER_RESULT_ERROR) + { + // BrotliDecoderErrorCode errcode = + BrotliDecoderGetErrorCode(decompress->br_state); + *outdata = NULL; + *outdata_len = 0; return -1; } @@ -234,20 +247,21 @@ int http_content_decompress_write(struct http_content_decompress *decompress, *outdata = NULL; *outdata_len = 0; - if(NULL == decompress->buffer ){ + if (NULL == decompress->buffer) + { decompress->buffer = CALLOC(char, HTTP_DECOMPRESS_BUFFER_SIZE); assert(decompress->buffer); decompress->buffer_size = HTTP_DECOMPRESS_BUFFER_SIZE; } if (decompress->encoding == HTTP_CONTENT_ENCODING_GZIP || - decompress->encoding == HTTP_CONTENT_ENCODING_DEFLATE) { - return http_content_decompress_write_zlib(decompress, indata, indata_len, - outdata, outdata_len); + decompress->encoding == HTTP_CONTENT_ENCODING_DEFLATE) + { + return http_content_decompress_write_zlib(decompress, indata, indata_len, outdata, outdata_len); } - if (decompress->encoding == HTTP_CONTENT_ENCODING_BR) { - return http_content_decompress_write_br(decompress, indata, indata_len, - outdata, outdata_len); + if (decompress->encoding == HTTP_CONTENT_ENCODING_BR) + { + return http_content_decompress_write_br(decompress, indata, indata_len, outdata, outdata_len); } assert(0); return -1; diff --git a/decoders/http/http_content_decompress.h b/decoders/http/http_content_decompress.h index 3c2ba48..7f2c221 100644 --- a/decoders/http/http_content_decompress.h +++ b/decoders/http/http_content_decompress.h @@ -1,16 +1,4 @@ -/* -********************************************************************************************** -* File: http_content_decompress.h -* Description: -* Authors: LuWenPeng -* Date: 2022-10-31 -* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved. -*********************************************************************************************** -*/ - - -#ifndef _HTTP_CONTENT_DECOMPRESS_H_ -#define _HTTP_CONTENT_DECOMPRESS_H_ +#pragma once #ifdef __cplusplus extern "C" @@ -19,34 +7,30 @@ extern "C" #include -enum http_content_encoding { - HTTP_CONTENT_ENCODING_NONE = 0, - HTTP_CONTENT_ENCODING_GZIP = 1 << 1, - HTTP_CONTENT_ENCODING_DEFLATE = 1 << 2, - HTTP_CONTENT_ENCODING_BR = 1 << 3, -}; + enum http_content_encoding + { + HTTP_CONTENT_ENCODING_NONE = 0, + HTTP_CONTENT_ENCODING_GZIP = 1 << 1, + HTTP_CONTENT_ENCODING_DEFLATE = 1 << 2, + HTTP_CONTENT_ENCODING_BR = 1 << 3, + }; -struct http_content_decompress; + struct http_content_decompress; -enum http_content_encoding -http_content_encoding_str2int(const char *content_encoding); + enum http_content_encoding http_content_encoding_str2int(const char *content_encoding); -const char * -http_content_encoding_int2str(enum http_content_encoding content_encoding); + const char *http_content_encoding_int2str(enum http_content_encoding content_encoding); -struct http_content_decompress * -http_content_decompress_create(enum http_content_encoding encoding); + struct http_content_decompress *http_content_decompress_create(enum http_content_encoding encoding); -void http_content_decompress_destroy(struct http_content_decompress *decompress); + void http_content_decompress_destroy(struct http_content_decompress *decompress); -// return 0 : success -// return -1 : error -int http_content_decompress_write(struct http_content_decompress *decompress, - const char *indata, size_t indata_len, - char **outdata, size_t *outdata_len); + // return 0 : success + // return -1 : error + int http_content_decompress_write(struct http_content_decompress *decompress, + const char *indata, size_t indata_len, + char **outdata, size_t *outdata_len); #ifdef __cplusplus } #endif - -#endif \ No newline at end of file diff --git a/decoders/http/http_decoder.cpp b/decoders/http/http_decoder.cpp index 218c508..f1c65f7 100644 --- a/decoders/http/http_decoder.cpp +++ b/decoders/http/http_decoder.cpp @@ -3,7 +3,7 @@ #include #include #include -#include "http_decoder_inc.h" +#include "http_decoder_private.h" #pragma GCC diagnostic ignored "-Wunused-parameter" @@ -123,7 +123,7 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d /* llhttp always call on_message_begin() even if llhttp_execute() error!!! */ msg = http_message_new(HTTP_TRANSACTION_START, queue, queue_idx, HTTP_REQUEST); session_mq_publish_message(ev_ctx->ref_session, exdata->pub_topic_id, msg); - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_TRANSACTION_NEW, 1); + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_TRANSACTION_NEW, 1); break; case HTTP_EVENT_REQ_LINE: msg = http_message_new(HTTP_MESSAGE_REQ_LINE, queue, queue_idx, HTTP_REQUEST); @@ -131,7 +131,7 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d if (httpd_tunnel_identify(httpd_env, FLOW_DIRECTION_C2S, half_data)) { exdata->tunnel_state = HTTP_TUN_C2S_HDR_START; - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_TUNNEL, 1); + // http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_TUNNEL, 1); } if (httpd_is_tunnel_session(httpd_env, exdata)) { @@ -157,11 +157,11 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d session_mq_publish_message(ev_ctx->ref_session, exdata->pub_topic_id, msg); int tot_c2s_headers = http_half_data_get_total_parsed_header_count(half_data); - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_HEADERS_C2S, tot_c2s_headers); + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_C2S_HEADERS, tot_c2s_headers); hstring tmp_url = {}; http_half_data_get_url(half_data, &tmp_url); - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_URL_BYTES, tmp_url.iov_len); + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_URL_BYTES, tmp_url.iov_len); } break; case HTTP_EVENT_REQ_BODY_BEGIN: @@ -176,9 +176,10 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d http_half_get_lastest_decompress_buffer(half_data, &decompress_body); msg = http_body_message_new(HTTP_MESSAGE_REQ_BODY, queue, queue_idx, HTTP_REQUEST, &raw_body, &decompress_body); session_mq_publish_message(ev_ctx->ref_session, exdata->pub_topic_id, msg); - if(decompress_body.iov_base != NULL){ - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_ZIP_BYTES, raw_body.iov_len); - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_UNZIP_BYTES, decompress_body.iov_len); + if (decompress_body.iov_base != NULL) + { + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_C2S_ZIP_BYTES, raw_body.iov_len); + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_C2S_UNZIP_BYTES, decompress_body.iov_len); } } break; @@ -194,8 +195,8 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d { msg = http_message_new(HTTP_TRANSACTION_END, queue, queue_idx, HTTP_REQUEST); session_mq_publish_message(ev_ctx->ref_session, exdata->pub_topic_id, msg); - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_TRANSACTION_FREE, 1); - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_ASYMMETRY_TRANSACTION_C2S, 1); + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_TRANSACTION_FREE, 1); + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_C2S_ASYMMETRY_TRANSACTION, 1); } if (httpd_is_tunnel_session(httpd_env, exdata)) { @@ -285,7 +286,7 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d session_mq_publish_message(ev_ctx->ref_session, exdata->pub_topic_id, msg); int tot_s2c_headers = http_half_data_get_total_parsed_header_count(half_data); - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_HEADERS_S2C, tot_s2c_headers); + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_S2C_HEADERS, tot_s2c_headers); if (httpd_is_tunnel_session(httpd_env, exdata)) { @@ -304,13 +305,14 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d hstring raw_body = {}; http_decoder_half_data_get_raw_body(half_data, &raw_body); hstring decompress_body = {}; - http_half_get_lastest_decompress_buffer(half_data, &decompress_body); + http_half_get_lastest_decompress_buffer(half_data, &decompress_body); msg = http_body_message_new(HTTP_MESSAGE_RES_BODY, queue, queue_idx, HTTP_RESPONSE, &raw_body, &decompress_body); session_mq_publish_message(ev_ctx->ref_session, exdata->pub_topic_id, msg); - if(decompress_body.iov_base != NULL){ - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_ZIP_BYTES, raw_body.iov_len); - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_UNZIP_BYTES, decompress_body.iov_len); - } + if (decompress_body.iov_base != NULL) + { + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_S2C_ZIP_BYTES, raw_body.iov_len); + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_S2C_UNZIP_BYTES, decompress_body.iov_len); + } } break; case HTTP_EVENT_RES_BODY_END: @@ -320,11 +322,11 @@ static void http_event_handler(enum http_event event, struct http_decoder_half_d case HTTP_EVENT_RES_END: msg = http_message_new(HTTP_TRANSACTION_END, queue, queue_idx, HTTP_RESPONSE); session_mq_publish_message(ev_ctx->ref_session, exdata->pub_topic_id, msg); - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_TRANSACTION_FREE, 1); + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_TRANSACTION_FREE, 1); session_is_symmetric(ev_ctx->ref_session, &flow_flag); if (SESSION_SEEN_S2C_FLOW == flow_flag) { - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_ASYMMETRY_TRANSACTION_S2C, 1); + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_S2C_ASYMMETRY_TRANSACTION, 1); } http_half_update_state(half_data, event); @@ -604,7 +606,7 @@ static struct http_decoder_exdata *httpd_session_exdata_new(struct session *sess httpd_env, req_start_seq, res_start_seq); // exdata->sub_topic_id = sub_topic_id; int thread_id = stellar_get_current_thread_index(); - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_SESSION_NEW, 1); + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_SESSION_NEW, 1); return exdata; } @@ -645,13 +647,13 @@ extern "C" if (SESSION_SEEN_C2S_FLOW == flow_flag) { - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_ASYMMETRY_SESSION_C2S, 1); + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_C2S_ASYMMETRY_SESSION, 1); } else if (SESSION_SEEN_S2C_FLOW == flow_flag) { - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_ASYMMETRY_SESSION_S2C, 1); + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_S2C_ASYMMETRY_SESSION, 1); } - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_SESSION_FREE, 1); + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_SESSION_FREE, 1); } static void http_decoder_execute(struct session *sess, struct http_decoder_env *httpd_env, http_decoder_exdata *exdata, const char *payload, uint16_t payload_len) @@ -669,21 +671,21 @@ extern "C" if (FLOW_DIRECTION_C2S == sess_dir) { cur_half = exdata->decoder->c2s_half; - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_BYTES_C2S, payload_len); - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_TCP_SEG_C2S, 1); + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_C2S_BYTES, payload_len); + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_C2S_TCP_SEG, 1); } else { cur_half = exdata->decoder->s2c_half; - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_BYTES_S2C, payload_len); - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_TCP_SEG_S2C, 1); + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_S2C_BYTES, payload_len); + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_S2C_TCP_SEG, 1); } http_decoder_half_reinit(cur_half, exdata->queue, exdata->mempool, sess); int ret = http_decoder_half_parse(httpd_env->hd_cfg.proxy_enable, cur_half, payload, payload_len); if (ret < 0) { - http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTPD_STAT_PARSE_ERR, 1); + http_decoder_stat_update(&httpd_env->hd_stat, thread_id, HTTP_STAT_PARSE_ERR, 1); stellar_session_plugin_dettach_current_session(sess); } } @@ -742,7 +744,7 @@ extern "C" if (NULL == exdata) { session_mq_ignore_message(sess, topic_id, httpd_env->plugin_id); - http_decoder_stat_update(&httpd_env->hd_stat, stellar_get_current_thread_index(), HTTPD_STAT_PARSE_ERR, 1); + http_decoder_stat_update(&httpd_env->hd_stat, stellar_get_current_thread_index(), HTTP_STAT_PARSE_ERR, 1); return; } break; @@ -750,7 +752,7 @@ extern "C" case HTTP_TUNNEL_CLOSING: if (NULL == exdata) { - http_decoder_stat_update(&httpd_env->hd_stat, stellar_get_current_thread_index(), HTTPD_STAT_PARSE_ERR, 1); + http_decoder_stat_update(&httpd_env->hd_stat, stellar_get_current_thread_index(), HTTP_STAT_PARSE_ERR, 1); return; } if (exdata->in_tunnel_is_http) @@ -1086,23 +1088,20 @@ extern "C" } /** * @brief If the body hasn't been compressed, same as http_message_raw_body_get0(). - * - */ - - if (HTTP_MESSAGE_REQ_BODY_START == msg->type - || HTTP_MESSAGE_REQ_BODY == msg->type - || HTTP_MESSAGE_REQ_BODY_END == msg->type) + * + */ + + if (HTTP_MESSAGE_REQ_BODY_START == msg->type || HTTP_MESSAGE_REQ_BODY == msg->type || HTTP_MESSAGE_REQ_BODY_END == msg->type) { ref_data = msg->ref_queue->array[msg->queue_index].req_data; } - else if (HTTP_MESSAGE_RES_BODY_START == msg->type - || HTTP_MESSAGE_RES_BODY == msg->type - || HTTP_MESSAGE_RES_BODY_END == msg->type) + else if (HTTP_MESSAGE_RES_BODY_START == msg->type || HTTP_MESSAGE_RES_BODY == msg->type || HTTP_MESSAGE_RES_BODY_END == msg->type) { ref_data = msg->ref_queue->array[msg->queue_index].res_data; } ecode = http_half_data_get_content_encoding(ref_data); - if(ref_data != NULL && HTTP_CONTENT_ENCODING_NONE != ecode){ + if (ref_data != NULL && HTTP_CONTENT_ENCODING_NONE != ecode) + { goto fail; } diff --git a/decoders/http/http_decoder_half.cpp b/decoders/http/http_decoder_half.cpp index bea97d0..a505fac 100644 --- a/decoders/http/http_decoder_half.cpp +++ b/decoders/http/http_decoder_half.cpp @@ -2,7 +2,7 @@ #include #include #include -#include "http_decoder_inc.h" +#include "http_decoder_private.h" #include "llhttp.h" #include "uthash/utlist.h" @@ -85,8 +85,7 @@ void http_half_decompress_buffer_free(struct http_decoder_half_data *data, hstri struct http_decompress_buffer *el, *tmp; DL_FOREACH_SAFE(data->decompress_buffer_list, el, tmp) { - if (el->iov.iov_base == decompress_body->iov_base - && el->iov.iov_len == decompress_body->iov_len) + if (el->iov.iov_base == decompress_body->iov_base && el->iov.iov_len == decompress_body->iov_len) { DL_DELETE(data->decompress_buffer_list, el); if (el->iov.iov_base) @@ -157,7 +156,7 @@ static void http_decoder_half_data_decompress(struct http_decoder_half_data *dat return; } - if(local_outdata!= NULL && local_outdata_len > 0) + if (local_outdata != NULL && local_outdata_len > 0) { struct http_decompress_buffer *decompress_buffer = CALLOC(struct http_decompress_buffer, 1); assert(decompress_buffer); @@ -873,7 +872,7 @@ static void http_decoder_half_decompress_buf_free(struct http_decoder_half_data if (el->iov.iov_base != NULL) { FREE(el->iov.iov_base); - } + } FREE(el); } ref_data->decompress_buffer_list = NULL; @@ -1208,7 +1207,7 @@ void http_half_get_max_transaction_seq(struct http_decoder_exdata *exdata, long enum http_content_encoding http_half_data_get_content_encoding(struct http_decoder_half_data *hf_data) { - if(NULL == hf_data) + if (NULL == hf_data) { return HTTP_CONTENT_ENCODING_NONE; } diff --git a/decoders/http/http_decoder_half.h b/decoders/http/http_decoder_half.h index 5deeaa6..adf61d1 100644 --- a/decoders/http/http_decoder_half.h +++ b/decoders/http/http_decoder_half.h @@ -1,15 +1,14 @@ -#ifndef _HTTP_DECODER_HALF_H_ -#define _HTTP_DECODER_HALF_H_ - +#pragma once #include #include "stellar/session.h" #include "stellar/http.h" #include "http_content_decompress.h" #include "http_decoder_result_queue.h" -#include "llhttp.h" +#include // only one http event is fired at a time -enum http_event { +enum http_event +{ HTTP_EVENT_REQ_INIT = 1 << 1, HTTP_EVENT_REQ_LINE = 1 << 2, HTTP_EVENT_REQ_HDR = 1 << 3, @@ -29,7 +28,8 @@ enum http_event { HTTP_EVENT_RES_END = 1 << 16, }; -struct http_event_context { +struct http_event_context +{ struct http_decoder_exdata *ref_httpd_ctx; nmx_pool_t *ref_mempool; struct session *ref_session; @@ -43,12 +43,12 @@ typedef void http_event_cb(enum http_event event, struct http_decoder_half_data struct http_event_context *ev_ctx, void *httpd_plugin_env); struct http_decoder_half * -http_decoder_half_new(struct http_decoder_exdata *hd_ctx, nmx_pool_t *mempool, http_event_cb *event_cb, - enum llhttp_type http_type, int decompress_switch, struct http_decoder_env *httpd_env,long long start_seq); +http_decoder_half_new(struct http_decoder_exdata *hd_ctx, nmx_pool_t *mempool, http_event_cb *event_cb, + enum llhttp_type http_type, int decompress_switch, struct http_decoder_env *httpd_env, long long start_seq); void http_decoder_half_free(nmx_pool_t *mempool, struct http_decoder_half *half); -void http_decoder_half_reinit(struct http_decoder_half *half, +void http_decoder_half_reinit(struct http_decoder_half *half, struct http_decoder_result_queue *queue, nmx_pool_t *mempool, struct session *sess); @@ -56,7 +56,7 @@ int http_decoder_half_parse(int proxy_enable, struct http_decoder_half *half, co long long http_decoder_half_trans_count(struct http_decoder_half *half); -//http decoder half data API +// http decoder half data API struct http_decoder_half_data * http_decoder_half_data_new(nmx_pool_t *mempool); @@ -90,16 +90,15 @@ void http_decoder_join_url(struct http_decoder_half_data *hfdata, nmx_pool_t *mempool, const struct http_header *host_hdr); int http_decoder_join_url_finally(struct http_event_context *ev_ctx, - struct http_decoder_half_data *hfdata, - nmx_pool_t *mempool); + struct http_decoder_half_data *hfdata, + nmx_pool_t *mempool); int http_half_data_get_url(struct http_decoder_half_data *res_data, hstring *url); int http_half_data_get_transaction_seq(struct http_decoder_half_data *hf_data); -void http_half_data_update_commit_index(struct http_decoder_half_data * half_data); +void http_half_data_update_commit_index(struct http_decoder_half_data *half_data); void http_half_pre_context_free(struct session *sess, struct http_decoder_exdata *exdata); -void http_half_update_state(struct http_decoder_half_data *hf_data, enum http_event state); -int http_half_data_get_total_parsed_header_count(struct http_decoder_half_data * half_data); -void http_half_get_max_transaction_seq(struct http_decoder_exdata *exdata, long long *max_req_seq, long long *max_res_seq); +void http_half_update_state(struct http_decoder_half_data *hf_data, enum http_event state); +int http_half_data_get_total_parsed_header_count(struct http_decoder_half_data *half_data); +void http_half_get_max_transaction_seq(struct http_decoder_exdata *exdata, long long *max_req_seq, long long *max_res_seq); -enum http_content_encoding http_half_data_get_content_encoding(struct http_decoder_half_data *hf_data); -#endif \ No newline at end of file +enum http_content_encoding http_half_data_get_content_encoding(struct http_decoder_half_data *hf_data); \ No newline at end of file diff --git a/decoders/http/http_decoder_inc.h b/decoders/http/http_decoder_inc.h deleted file mode 100644 index 52c364f..0000000 --- a/decoders/http/http_decoder_inc.h +++ /dev/null @@ -1,162 +0,0 @@ -/* -********************************************************************************************** -* File: http_decoder_inc.h -* Description: -* Authors: Liu WenTan -* Date: 2024-01-10 -* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved. -*********************************************************************************************** -*/ - -#ifndef _HTTP_DECODER_INC_H_ -#define _HTTP_DECODER_INC_H_ - -#ifndef __USE_MISC -#define __USE_MISC 1 -#endif - -#include -#ifdef __cplusplus -extern "C" -{ -#endif -#include -#include "stellar/stellar.h" -#include "stellar/layer.h" -#include "stellar/packet.h" -#include "stellar/utils.h" -#include "stellar/session.h" -#include "stellar/stellar_mq.h" -#include "stellar/stellar_exdata.h" - -#include "nmx_pool/nmx_palloc.h" -#include "stellar/utils.h" -#include "stellar/http.h" -#include "http_decoder_result_queue.h" -#include "http_decoder_half.h" -#include "http_decoder_table.h" -#include "http_decoder_result_queue.h" -#include "http_decoder_utils.h" -#include "http_decoder_stat.h" -#include "http_decoder_tunnel.h" -#include "fieldstat/fieldstat_easy.h" -#include "toml/toml.h" - -#ifndef likely -#define likely(x) __builtin_expect((x), 1) -#endif -#ifndef unlikely -#define unlikely(x) __builtin_expect((x), 0) -#endif - -#define MEMPOOL_CALLOC(pool, type, number) ((type *)nmx_pcalloc(pool, sizeof(type) * number)) -#define MEMPOOL_REALLOC(pool) -#define MEMPOOL_FREE(pool, p) nmx_pfree(pool, p) - -#define ENABLE_MEMPOOL 0 -#if ENABLE_MEMPOOL -#define HD_CALLOC(pool, type, number) MEMPOOL_CALLOC(pool, number, type) -#define HD_FREE(pool, p) MEMPOOL_FREE(pool, p) -#else -#define HD_CALLOC(pool, type, number) CALLOC(type, number) -#define HD_FREE(pool, p) FREE(p) -#endif - -#define HTTP_IDENTIFY_LEN 16 -#define HD_RESULT_QUEUE_LEN 16 - -#define DEFAULT_STAT_OUTPUT_INTERVAL 1 -#define DEFAULT_STAT_INTERVAL_PKTS 1000 -#define DEFAULT_MEMPOOL_SIZE (32 * 1024) - -#define HTTPD_CFG_FILE "./etc/http/http_decoder.toml" -#define FILEDSTAT_OUTPUT_FILE "./metrics/http_decoder_fs4.json" - -#define HTTP_CTX_NOT_HTTP "__NOT_HTTP_SESS__" -#define HTTP_CTX_IS_HTTP "__FAKE_HTTP_CTX__" - -struct http_decoder_config -{ - int decompress_switch; - int stat_interval_pkts; // call fieldstat_incrby every stat_interval_pkts - int stat_output_interval; - int proxy_enable; - size_t result_queue_len; // per session result queue length - size_t mempool_size; // per session mempool size -}; - -/** - * NOTE: http_message don't have the ownership of data - */ -struct http_message -{ - uint8_t flow_type; - enum http_message_type type; - size_t queue_index; - struct http_decoder_result_queue *ref_queue; - hstring raw_payload;//cause tcp reorder, maybe receive many tcp segments for one packet - hstring decompress_payload; - hstring tunnel_payload; -}; - -struct http_decoder -{ - struct http_decoder_half *c2s_half; - struct http_decoder_half *s2c_half; -}; - -enum httpd_topic_index{ - HTTPD_TOPIC_TCP_STREAM_INDEX = 0, - HTTPD_TOPIC_HTTP_MSG_INDEX, - HTTPD_TOPIC_HTTP_TUNNEL_INDEX, - HTTPD_TOPIC_INDEX_MAX, -}; - -struct http_decoder_exdata -{ - int sub_topic_id; //tcp_stream - int pub_topic_id; //http message or http tunnel msg - struct http_decoder_result_queue *queue; - struct http_decoder *decoder; - nmx_pool_t *mempool; - enum http_tunnel_state tunnel_state; - int in_tunnel_is_http; -}; - -// struct http_decoder_context{ -// int array_size; -// struct http_decoder_exdata **exdata_array; //raw tcp stream for http msg; http tunnel for inner http transaction. -// }; - -struct http_topic_exdata_compose{ - enum httpd_topic_index index; - const char *topic_name; - on_session_msg_cb_func *on_msg_cb; - stellar_msg_free_cb_func *msg_free_cb; - const char *exdata_name; - stellar_exdata_free *exdata_free_cb; - int sub_topic_id; //as consumer - int exdata_id; -}; - -struct http_decoder_env -{ - struct stellar *st; - int plugin_id; - struct http_topic_exdata_compose topic_exdata_compose[HTTPD_TOPIC_INDEX_MAX]; - struct http_decoder_config hd_cfg; - struct http_decoder_stat hd_stat; -}; - -struct http_message; - -struct http_message *http_message_new(enum http_message_type type, struct http_decoder_result_queue *queue, - int queue_index, unsigned char flow_type); -struct http_message *http_body_message_new(enum http_message_type type, struct http_decoder_result_queue *queue, - int queue_index, uint8_t flow_type, hstring *raw_payload); -int http_topic_exdata_compose_get_index(const struct http_decoder_env *httpd_env, int by_topic_id); -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/decoders/http/http_decoder_private.h b/decoders/http/http_decoder_private.h new file mode 100644 index 0000000..8c071e8 --- /dev/null +++ b/decoders/http/http_decoder_private.h @@ -0,0 +1,152 @@ + +#pragma once + +#ifndef __USE_MISC +#define __USE_MISC 1 +#endif + +#include +#ifdef __cplusplus +extern "C" +{ +#endif +#include +#include "stellar/stellar.h" +#include "stellar/layer.h" +#include "stellar/packet.h" +#include "stellar/utils.h" +#include "stellar/session.h" +#include "stellar/stellar_mq.h" +#include "stellar/stellar_exdata.h" + +#include "nmx_pool/nmx_palloc.h" +#include "stellar/utils.h" +#include "stellar/http.h" +#include "http_decoder_result_queue.h" +#include "http_decoder_half.h" +#include "http_decoder_table.h" +#include "http_decoder_result_queue.h" +#include "http_decoder_utils.h" +#include "http_decoder_stat.h" +#include "http_decoder_tunnel.h" +#include "fieldstat/fieldstat_easy.h" +#include "toml/toml.h" + +#ifndef likely +#define likely(x) __builtin_expect((x), 1) +#endif +#ifndef unlikely +#define unlikely(x) __builtin_expect((x), 0) +#endif + +#define MEMPOOL_CALLOC(pool, type, number) ((type *)nmx_pcalloc(pool, sizeof(type) * number)) +#define MEMPOOL_REALLOC(pool) +#define MEMPOOL_FREE(pool, p) nmx_pfree(pool, p) + +#define ENABLE_MEMPOOL 0 +#if ENABLE_MEMPOOL +#define HD_CALLOC(pool, type, number) MEMPOOL_CALLOC(pool, number, type) +#define HD_FREE(pool, p) MEMPOOL_FREE(pool, p) +#else +#define HD_CALLOC(pool, type, number) CALLOC(type, number) +#define HD_FREE(pool, p) FREE(p) +#endif + +#define HTTP_IDENTIFY_LEN 16 +#define HD_RESULT_QUEUE_LEN 16 + +#define DEFAULT_STAT_OUTPUT_INTERVAL 1 +#define DEFAULT_STAT_INTERVAL_PKTS 1000 +#define DEFAULT_MEMPOOL_SIZE (32 * 1024) + +#define HTTPD_CFG_FILE "./etc/http/http_decoder.toml" +#define FILEDSTAT_OUTPUT_FILE "./metrics/http_decoder_fs4.json" + +#define HTTP_CTX_NOT_HTTP "__NOT_HTTP_SESS__" +#define HTTP_CTX_IS_HTTP "__FAKE_HTTP_CTX__" + + struct http_decoder_config + { + int decompress_switch; + int stat_interval_pkts; // call fieldstat_incrby every stat_interval_pkts + int stat_output_interval; + int proxy_enable; + size_t result_queue_len; // per session result queue length + size_t mempool_size; // per session mempool size + }; + + /** + * NOTE: http_message don't have the ownership of data + */ + struct http_message + { + uint8_t flow_type; + enum http_message_type type; + size_t queue_index; + struct http_decoder_result_queue *ref_queue; + hstring raw_payload; // cause tcp reorder, maybe receive many tcp segments for one packet + hstring decompress_payload; + hstring tunnel_payload; + }; + + struct http_decoder + { + struct http_decoder_half *c2s_half; + struct http_decoder_half *s2c_half; + }; + + enum httpd_topic_index + { + HTTPD_TOPIC_TCP_STREAM_INDEX = 0, + HTTPD_TOPIC_HTTP_MSG_INDEX, + HTTPD_TOPIC_HTTP_TUNNEL_INDEX, + HTTPD_TOPIC_INDEX_MAX, + }; + + struct http_decoder_exdata + { + int sub_topic_id; // tcp_stream + int pub_topic_id; // http message or http tunnel msg + struct http_decoder_result_queue *queue; + struct http_decoder *decoder; + nmx_pool_t *mempool; + enum http_tunnel_state tunnel_state; + int in_tunnel_is_http; + }; + + // struct http_decoder_context{ + // int array_size; + // struct http_decoder_exdata **exdata_array; //raw tcp stream for http msg; http tunnel for inner http transaction. + // }; + + struct http_topic_exdata_compose + { + enum httpd_topic_index index; + const char *topic_name; + on_session_msg_cb_func *on_msg_cb; + stellar_msg_free_cb_func *msg_free_cb; + const char *exdata_name; + stellar_exdata_free *exdata_free_cb; + int sub_topic_id; // as consumer + int exdata_id; + }; + + struct http_decoder_env + { + struct stellar *st; + int plugin_id; + struct http_topic_exdata_compose topic_exdata_compose[HTTPD_TOPIC_INDEX_MAX]; + struct http_decoder_config hd_cfg; + struct http_decoder_stat hd_stat; + }; + + struct http_message; + + struct http_message *http_message_new(enum http_message_type type, struct http_decoder_result_queue *queue, + int queue_index, unsigned char flow_type); + struct http_message *http_body_message_new(enum http_message_type type, struct http_decoder_result_queue *queue, + int queue_index, uint8_t flow_type, hstring *raw_payload); + int http_topic_exdata_compose_get_index(const struct http_decoder_env *httpd_env, int by_topic_id); +#ifdef __cplusplus +} +#endif diff --git a/decoders/http/http_decoder_result_queue.cpp b/decoders/http/http_decoder_result_queue.cpp index 6a5e003..5695138 100644 --- a/decoders/http/http_decoder_result_queue.cpp +++ b/decoders/http/http_decoder_result_queue.cpp @@ -1,14 +1,5 @@ -/* -********************************************************************************************** -* File: http_decoder_result_queue.c -* Description: -* Authors: Liuwentan -* Date: 2024-01-15 -* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved. -*********************************************************************************************** -*/ #include -#include "http_decoder_inc.h" +#include "http_decoder_private.h" struct http_decoder_result_queue * http_decoder_result_queue_new(nmx_pool_t *mempool, size_t queue_size) @@ -28,23 +19,28 @@ http_decoder_result_queue_new(nmx_pool_t *mempool, size_t queue_size) void http_decoder_result_queue_free(nmx_pool_t *mempool, struct http_decoder_result_queue *queue) { - if (NULL == queue) { - return; + if (NULL == queue) + { + return; } - if (queue->array != NULL) { - for (size_t i = 0; i < queue->queue_size; i++) { - if (queue->array[i].req_data != NULL) { - http_decoder_half_data_free(mempool, queue->array[i].req_data); - queue->array[i].req_data = NULL; + if (queue->array != NULL) + { + for (size_t i = 0; i < queue->queue_size; i++) + { + if (queue->array[i].req_data != NULL) + { + http_decoder_half_data_free(mempool, queue->array[i].req_data); + queue->array[i].req_data = NULL; } - if (queue->array[i].res_data != NULL) { - http_decoder_half_data_free(mempool, queue->array[i].res_data); - queue->array[i].res_data = NULL; + if (queue->array[i].res_data != NULL) + { + http_decoder_half_data_free(mempool, queue->array[i].res_data); + queue->array[i].res_data = NULL; } } - MEMPOOL_FREE(mempool, queue->array); + MEMPOOL_FREE(mempool, queue->array); } MEMPOOL_FREE(mempool, queue); } @@ -78,11 +74,13 @@ size_t http_decoder_result_queue_res_index(struct http_decoder_result_queue *que int http_decoder_result_queue_push_req(struct http_decoder_result_queue *queue, struct http_decoder_half_data *req_data) { - if (NULL == queue || NULL == req_data) { + if (NULL == queue || NULL == req_data) + { return -1; } assert(queue->array[queue->req_index].req_data == NULL); - if (queue->array[queue->req_index].req_data != NULL) { + if (queue->array[queue->req_index].req_data != NULL) + { return -1; } queue->array[queue->req_index].req_data = req_data; @@ -92,11 +90,13 @@ int http_decoder_result_queue_push_req(struct http_decoder_result_queue *queue, int http_decoder_result_queue_push_res(struct http_decoder_result_queue *queue, struct http_decoder_half_data *res_data) { - if (NULL == queue || NULL == res_data) { + if (NULL == queue || NULL == res_data) + { return -1; } assert(queue->array[queue->res_index].res_data == NULL); - if (queue->array[queue->res_index].res_data != NULL) { + if (queue->array[queue->res_index].res_data != NULL) + { return -1; } @@ -107,7 +107,8 @@ int http_decoder_result_queue_push_res(struct http_decoder_result_queue *queue, struct http_decoder_half_data * http_decoder_result_queue_pop_req(struct http_decoder_result_queue *queue) { - if (NULL == queue) { + if (NULL == queue) + { return NULL; } struct http_decoder_half_data *req_data = queue->array[queue->req_index].req_data; @@ -118,7 +119,8 @@ http_decoder_result_queue_pop_req(struct http_decoder_result_queue *queue) struct http_decoder_half_data * http_decoder_result_queue_pop_res(struct http_decoder_result_queue *queue) { - if (NULL == queue) { + if (NULL == queue) + { return NULL; } @@ -130,7 +132,8 @@ http_decoder_result_queue_pop_res(struct http_decoder_result_queue *queue) struct http_decoder_half_data * http_decoder_result_queue_peek_req(struct http_decoder_result_queue *queue) { - if (NULL == queue) { + if (NULL == queue) + { return NULL; } assert(queue->req_index < queue->queue_size); @@ -140,7 +143,8 @@ http_decoder_result_queue_peek_req(struct http_decoder_result_queue *queue) struct http_decoder_half_data * http_decoder_result_queue_peek_res(struct http_decoder_result_queue *queue) { - if (NULL == queue) { + if (NULL == queue) + { return NULL; } assert(queue->res_index < queue->queue_size); diff --git a/decoders/http/http_decoder_result_queue.h b/decoders/http/http_decoder_result_queue.h index 97d68a6..a6ff0ca 100644 --- a/decoders/http/http_decoder_result_queue.h +++ b/decoders/http/http_decoder_result_queue.h @@ -1,29 +1,21 @@ -/* -********************************************************************************************** -* File: http_decoder_result_queue.h -* Description: -* Authors: Liuwentan -* Date: 2024-01-15 -* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved. -*********************************************************************************************** -*/ -#ifndef _HTTP_DECODER_RESULT_QUEUE_H_ -#define _HTTP_DECODER_RESULT_QUEUE_H_ +#pragma once #include #include "nmx_pool/nmx_palloc.h" #include "http_decoder_half.h" -struct http_decoder_result { +struct http_decoder_result +{ struct http_decoder_half_data *req_data; struct http_decoder_half_data *res_data; }; -struct http_decoder_result_queue { - size_t req_index; - size_t res_index; - size_t queue_size; - struct http_decoder_result *array; +struct http_decoder_result_queue +{ + size_t req_index; + size_t res_index; + size_t queue_size; + struct http_decoder_result *array; }; struct http_decoder_result_queue * @@ -57,5 +49,3 @@ http_decoder_result_queue_peek_req(struct http_decoder_result_queue *queue); struct http_decoder_half_data * http_decoder_result_queue_peek_res(struct http_decoder_result_queue *queue); - -#endif \ No newline at end of file diff --git a/decoders/http/http_decoder_stat.cpp b/decoders/http/http_decoder_stat.cpp index f616658..dec6c91 100644 --- a/decoders/http/http_decoder_stat.cpp +++ b/decoders/http/http_decoder_stat.cpp @@ -2,41 +2,44 @@ #include #include #include -#include "http_decoder_inc.h" +#include "http_decoder_private.h" -static const struct hd_stat_config_tuple g_httpd_stat_tuple[HTTPD_STAT_MAX] = -{ - {HTTPD_STAT_BYTES_C2S, "bytes_c2s"}, - {HTTPD_STAT_BYTES_S2C, "bytes_s2c"}, - {HTTPD_STAT_TCP_SEG_C2S, "tcp_seg_c2s"}, - {HTTPD_STAT_TCP_SEG_S2C, "tcp_seg_s2c"}, - {HTTPD_STAT_HEADERS_C2S, "headers_c2s"}, - {HTTPD_STAT_HEADERS_S2C, "headers_s2c"}, - {HTTPD_STAT_ZIP_BYTES, "zip_bytes"}, - {HTTPD_STAT_UNZIP_BYTES, "unzip_bytes"}, - {HTTPD_STAT_URL_BYTES, "url_bytes"}, - {HTTPD_STAT_SESSION_NEW, "session_new"}, - {HTTPD_STAT_SESSION_FREE, "session_free"}, - {HTTPD_STAT_SESSION_EXCEPTION, "sess_exception"}, - {HTTPD_STAT_TUNNEL, "tunnel"}, - {HTTPD_STAT_TRANSACTION_NEW, "trans_new"}, - {HTTPD_STAT_TRANSACTION_FREE, "trans_free"}, - {HTTPD_STAT_ASYMMETRY_SESSION_C2S, "asymmetry_sess_c2s"}, - {HTTPD_STAT_ASYMMETRY_SESSION_S2C, "asymmetry_sess_s2c"}, - {HTTPD_STAT_ASYMMETRY_TRANSACTION_C2S, "asymmetry_trans_c2s"}, - {HTTPD_STAT_ASYMMETRY_TRANSACTION_S2C, "asymmetry_trans_s2c"}, - {HTTPD_STAT_PARSE_ERR, "parse_err"}, -}; +static const struct hd_stat_config_tuple g_httpd_stat_tuple[HTTP_STAT_MAX] = + { + {HTTP_C2S_BYTES, "http_c2s_bytes"}, + {HTTP_S2C_BYTES, "http_s2c_bytes"}, + {HTTP_C2S_TCP_SEG, "http_c2s_tcp_seg"}, + {HTTP_S2C_TCP_SEG, "http_s2c_tcp_seg"}, + {HTTP_C2S_HEADERS, "http_c2s_headers"}, + {HTTP_S2C_HEADERS, "http_s2c_headers"}, + {HTTP_C2S_ZIP_BYTES, "http_c2s_zip_bytes"}, + {HTTP_S2C_ZIP_BYTES, "http_s2c_zip_bytes"}, + {HTTP_C2S_UNZIP_BYTES, "http_c2s_unzip_bytes"}, + {HTTP_S2C_UNZIP_BYTES, "http_s2c_unzip_bytes"}, + {HTTP_URL_BYTES, "http_url_bytes"}, + {HTTP_SESSION_NEW, "http_session_new"}, + {HTTP_SESSION_FREE, "http_session_free"}, + {HTTP_TRANSACTION_NEW, "http_transaction_new"}, + {HTTP_TRANSACTION_FREE, "http_transaction_free"}, + {HTTP_C2S_ASYMMETRY_SESSION, "http_c2s_asymmetry_sess"}, + {HTTP_S2C_ASYMMETRY_SESSION, "http_s2c_asymmetry_sess"}, + {HTTP_C2S_ASYMMETRY_TRANSACTION, "http_c2s_asymmetry_trans"}, + {HTTP_S2C_ASYMMETRY_TRANSACTION, "http_s2c_asymmetry_trans"}, + {HTTP_STAT_PARSE_ERR, "http_parse_error"}, +}; void http_decoder_stat_free(struct http_decoder_stat *hd_stat) { - if(hd_stat->timer_pid != 0){ + if (hd_stat->timer_pid != 0) + { pthread_cancel(hd_stat->timer_pid); } - if(hd_stat->stats != NULL){ + if (hd_stat->stats != NULL) + { free(hd_stat->stats); } - if(hd_stat->fse != NULL){ + if (hd_stat->fse != NULL) + { fieldstat_easy_free(hd_stat->fse); } } @@ -46,7 +49,8 @@ static void *httpd_stat_timer_thread(void *arg) pthread_setname_np(pthread_self(), "http_decoder_timer_thread"); struct http_decoder_stat *hd_stat = (struct http_decoder_stat *)arg; struct timespec res; - while(1){ + while (1) + { clock_gettime(CLOCK_MONOTONIC, &res); hd_stat->current_time_ms = (res.tv_sec * 1000) + (res.tv_nsec / 1000000); usleep(800); @@ -56,8 +60,9 @@ static void *httpd_stat_timer_thread(void *arg) int http_decoder_stat_init(struct http_decoder_stat *hd_stat, int thread_max, int stat_interval_pkts, int stat_interval_time) { - assert(sizeof(g_httpd_stat_tuple)/sizeof(struct hd_stat_config_tuple) == HTTPD_STAT_MAX); - if(sizeof(g_httpd_stat_tuple)/sizeof(struct hd_stat_config_tuple) != HTTPD_STAT_MAX){ + assert(sizeof(g_httpd_stat_tuple) / sizeof(struct hd_stat_config_tuple) == HTTP_STAT_MAX); + if (sizeof(g_httpd_stat_tuple) / sizeof(struct hd_stat_config_tuple) != HTTP_STAT_MAX) + { fprintf(stderr, "enum http_decoder_stat_type number not match with g_httpd_stat_tuple!"); return -1; } @@ -68,7 +73,7 @@ int http_decoder_stat_init(struct http_decoder_stat *hd_stat, int thread_max, in return -1; } - for(int i = 0; i < HTTPD_STAT_MAX; i++) + for (int i = 0; i < HTTP_STAT_MAX; i++) { hd_stat->field_stat_id[i] = fieldstat_easy_register_counter(hd_stat->fse, g_httpd_stat_tuple[i].name); if (hd_stat->field_stat_id[i] < 0) @@ -79,13 +84,13 @@ int http_decoder_stat_init(struct http_decoder_stat *hd_stat, int thread_max, in return -1; } } - + int ret = fieldstat_easy_enable_auto_output(hd_stat->fse, FILEDSTAT_OUTPUT_FILE, stat_interval_time); if (ret < 0) { fprintf(stderr, "fieldstat_easy_enable_auto_output failed."); fieldstat_easy_free(hd_stat->fse); - hd_stat->fse = NULL; + hd_stat->fse = NULL; return -1; } hd_stat->stats = (struct hd_statistics *)calloc(thread_max, sizeof(struct hd_statistics)); @@ -100,9 +105,10 @@ void http_decoder_stat_update(struct http_decoder_stat *hd_stat, int thread_id, { assert(hd_stat); assert(thread_id >= 0); - assert(type < HTTPD_STAT_MAX); + assert(type < HTTP_STAT_MAX); - if(unlikely(hd_stat->stats == NULL)){ + if (unlikely(hd_stat->stats == NULL)) + { return; } @@ -111,11 +117,11 @@ void http_decoder_stat_update(struct http_decoder_stat *hd_stat, int thread_id, cur_hds->counter[type] += value; cur_hds->batch[type]++; - if(cur_hds->batch[type] >= hd_stat->stat_interval_pkts - || cur_hds->time_ms[type] + 1000 < hd_stat->current_time_ms){ - fieldstat_easy_counter_incrby(hd_stat->fse, thread_id, hd_stat->field_stat_id[type], NULL, 0, cur_hds->counter[type]); - cur_hds->counter[type] = 0; - cur_hds->batch[type] = 0; - cur_hds->time_ms[type] = hd_stat->current_time_ms; + if (cur_hds->batch[type] >= hd_stat->stat_interval_pkts || cur_hds->time_ms[type] + 1000 < hd_stat->current_time_ms) + { + fieldstat_easy_counter_incrby(hd_stat->fse, thread_id, hd_stat->field_stat_id[type], NULL, 0, cur_hds->counter[type]); + cur_hds->counter[type] = 0; + cur_hds->batch[type] = 0; + cur_hds->time_ms[type] = hd_stat->current_time_ms; } } \ No newline at end of file diff --git a/decoders/http/http_decoder_stat.h b/decoders/http/http_decoder_stat.h index 719e6a0..339e81d 100644 --- a/decoders/http/http_decoder_stat.h +++ b/decoders/http/http_decoder_stat.h @@ -1,30 +1,29 @@ -#ifndef _HTTP_DECODER_STAT_H_ -#define _HTTP_DECODER_STAT_H_ 1 +#pragma once #include enum http_decoder_stat_type { - HTTPD_STAT_BYTES_C2S = 0, - HTTPD_STAT_BYTES_S2C, - HTTPD_STAT_TCP_SEG_C2S, - HTTPD_STAT_TCP_SEG_S2C, - HTTPD_STAT_HEADERS_C2S, - HTTPD_STAT_HEADERS_S2C, - HTTPD_STAT_ZIP_BYTES, //only if Content-Encoding is gzip, deflate, br - HTTPD_STAT_UNZIP_BYTES, //only if Content-Encoding is gzip, deflate, br - HTTPD_STAT_URL_BYTES, - HTTPD_STAT_SESSION_NEW, - HTTPD_STAT_SESSION_FREE, - HTTPD_STAT_SESSION_EXCEPTION, // rst, kickout, lost packet, etc. - HTTPD_STAT_TUNNEL, - HTTPD_STAT_TRANSACTION_NEW, - HTTPD_STAT_TRANSACTION_FREE, - HTTPD_STAT_ASYMMETRY_SESSION_C2S, - HTTPD_STAT_ASYMMETRY_SESSION_S2C, - HTTPD_STAT_ASYMMETRY_TRANSACTION_C2S, - HTTPD_STAT_ASYMMETRY_TRANSACTION_S2C, - HTTPD_STAT_PARSE_ERR, - HTTPD_STAT_MAX, + HTTP_C2S_BYTES = 0, + HTTP_S2C_BYTES, + HTTP_C2S_TCP_SEG, + HTTP_S2C_TCP_SEG, + HTTP_C2S_HEADERS, + HTTP_S2C_HEADERS, + HTTP_C2S_ZIP_BYTES, // only if Content-Encoding is gzip, deflate, br + HTTP_S2C_ZIP_BYTES, // only if Content-Encoding is gzip, deflate, br + HTTP_C2S_UNZIP_BYTES, // only if Content-Encoding is gzip, deflate, br + HTTP_S2C_UNZIP_BYTES, // only if Content-Encoding is gzip, deflate, br + HTTP_URL_BYTES, + HTTP_SESSION_NEW, + HTTP_SESSION_FREE, + HTTP_TRANSACTION_NEW, + HTTP_TRANSACTION_FREE, + HTTP_C2S_ASYMMETRY_SESSION, + HTTP_S2C_ASYMMETRY_SESSION, + HTTP_C2S_ASYMMETRY_TRANSACTION, + HTTP_S2C_ASYMMETRY_TRANSACTION, + HTTP_STAT_PARSE_ERR, + HTTP_STAT_MAX, }; struct hd_stat_config_tuple @@ -35,10 +34,10 @@ struct hd_stat_config_tuple struct hd_statistics { - long long time_ms[HTTPD_STAT_MAX]; - long long counter[HTTPD_STAT_MAX]; - int batch[HTTPD_STAT_MAX]; //call fieldstat_easy_counter_incrby() per batch -}__attribute__ ((aligned (64))); + long long time_ms[HTTP_STAT_MAX]; + long long counter[HTTP_STAT_MAX]; + int batch[HTTP_STAT_MAX]; // call fieldstat_easy_counter_incrby() per batch +} __attribute__((aligned(64))); struct http_decoder_stat { @@ -46,12 +45,11 @@ struct http_decoder_stat long long current_time_ms; struct fieldstat_easy *fse; int stat_interval_pkts; // call fieldstat_incrby every stat_interval_pkts - int stat_interval_time; //second - int field_stat_id[HTTPD_STAT_MAX]; - struct hd_statistics *stats; //size is thread number + int stat_interval_time; // second + int field_stat_id[HTTP_STAT_MAX]; + struct hd_statistics *stats; // size is thread number }; int http_decoder_stat_init(struct http_decoder_stat *hd_stat, int thread_max, int stat_interval_pkts, int stat_interval_time); void http_decoder_stat_free(struct http_decoder_stat *hd_stat); void http_decoder_stat_update(struct http_decoder_stat *hd_stat, int thread_id, enum http_decoder_stat_type type, long long value); -#endif \ No newline at end of file diff --git a/decoders/http/http_decoder_string.cpp b/decoders/http/http_decoder_string.cpp index d54d22b..88abd17 100644 --- a/decoders/http/http_decoder_string.cpp +++ b/decoders/http/http_decoder_string.cpp @@ -2,11 +2,12 @@ #include #include #include -#include "http_decoder_inc.h" +#include "http_decoder_private.h" static const char *string_state_to_desc(enum string_state state) { - switch (state) { + switch (state) + { case STRING_STATE_INIT: return "init"; break; @@ -25,22 +26,23 @@ static const char *string_state_to_desc(enum string_state state) } } -void http_decoder_string_refer(struct http_decoder_string *rstr, - const char *at, size_t length) +void http_decoder_string_refer(struct http_decoder_string *rstr, const char *at, size_t length) { - if (NULL == rstr) { + if (NULL == rstr) + { return; } - switch (rstr->state) { - case STRING_STATE_INIT: - case STRING_STATE_CACHE: - rstr->refer.iov_base = (char *)at; - rstr->refer.iov_len = length; - break; - default: - abort(); - break; + switch (rstr->state) + { + case STRING_STATE_INIT: + case STRING_STATE_CACHE: + rstr->refer.iov_base = (char *)at; + rstr->refer.iov_len = length; + break; + default: + abort(); + break; } rstr->state = STRING_STATE_REFER; @@ -48,22 +50,28 @@ void http_decoder_string_refer(struct http_decoder_string *rstr, static void string_refer2cache(struct http_decoder_string *rstr) { - if (0 == rstr->refer.iov_len) { + if (0 == rstr->refer.iov_len) + { return; } - if (rstr->cache.iov_len >= rstr->max_cache_size) { + if (rstr->cache.iov_len >= rstr->max_cache_size) + { return; } size_t length = rstr->cache.iov_len + rstr->refer.iov_len; - if (length > rstr->max_cache_size) { + if (length > rstr->max_cache_size) + { length = rstr->max_cache_size; } - if (NULL == rstr->cache.iov_base) { + if (NULL == rstr->cache.iov_base) + { rstr->cache.iov_base = CALLOC(char, length + 1); memcpy(rstr->cache.iov_base, rstr->refer.iov_base, length); - } else { + } + else + { rstr->cache.iov_base = REALLOC(char, rstr->cache.iov_base, length + 1); memcpy((char *)rstr->cache.iov_base + rstr->cache.iov_len, rstr->refer.iov_base, (length - rstr->cache.iov_len)); @@ -77,24 +85,32 @@ static void string_refer2cache(struct http_decoder_string *rstr) static void string_commit2cache(struct http_decoder_string *rstr) { if (rstr->cache.iov_len == rstr->commit.iov_len && - rstr->cache.iov_base == rstr->commit.iov_base) { + rstr->cache.iov_base == rstr->commit.iov_base) + { rstr->commit.iov_base = NULL; rstr->commit.iov_len = 0; return; } - //Only http header key need to backward to cache + // Only http header key need to backward to cache size_t length = 0; - if (rstr->commit.iov_len > rstr->max_cache_size) { + if (rstr->commit.iov_len > rstr->max_cache_size) + { length = rstr->max_cache_size; - } else { + } + else + { length = rstr->commit.iov_len; } - if (length > 0) { - if (NULL == rstr->cache.iov_base) { + if (length > 0) + { + if (NULL == rstr->cache.iov_base) + { rstr->cache.iov_base = CALLOC(char, length + 1); - } else { + } + else + { abort(); } memcpy(rstr->cache.iov_base, rstr->commit.iov_base, length); @@ -107,18 +123,20 @@ static void string_commit2cache(struct http_decoder_string *rstr) void http_decoder_string_cache(struct http_decoder_string *rstr) { - if (NULL == rstr) { + if (NULL == rstr) + { return; } - switch (rstr->state) { + switch (rstr->state) + { case STRING_STATE_REFER: string_refer2cache(rstr); break; case STRING_STATE_CACHE: break; case STRING_STATE_COMMIT: - //commit backward to cache + // commit backward to cache string_commit2cache(rstr); break; default: @@ -130,34 +148,39 @@ void http_decoder_string_cache(struct http_decoder_string *rstr) void http_decoder_string_commit(struct http_decoder_string *rstr) { - if (NULL == rstr) { + if (NULL == rstr) + { return; } - switch (rstr->state) { - case STRING_STATE_REFER: - if (rstr->cache.iov_len) { - http_decoder_string_cache(rstr); + switch (rstr->state) + { + case STRING_STATE_REFER: + if (rstr->cache.iov_len) + { + http_decoder_string_cache(rstr); - rstr->commit.iov_base = rstr->cache.iov_base; - rstr->commit.iov_len = rstr->cache.iov_len; - // not overwrite rstr->cache.iov_base - } else { - rstr->commit.iov_base = rstr->refer.iov_base; - rstr->commit.iov_len = rstr->refer.iov_len; - - rstr->refer.iov_base = NULL; - rstr->refer.iov_len = 0; - } - break; - case STRING_STATE_CACHE: rstr->commit.iov_base = rstr->cache.iov_base; rstr->commit.iov_len = rstr->cache.iov_len; // not overwrite rstr->cache.iov_base - break; - default: - //abort(); - break; + } + else + { + rstr->commit.iov_base = rstr->refer.iov_base; + rstr->commit.iov_len = rstr->refer.iov_len; + + rstr->refer.iov_base = NULL; + rstr->refer.iov_len = 0; + } + break; + case STRING_STATE_CACHE: + rstr->commit.iov_base = rstr->cache.iov_base; + rstr->commit.iov_len = rstr->cache.iov_len; + // not overwrite rstr->cache.iov_base + break; + default: + // abort(); + break; } rstr->state = STRING_STATE_COMMIT; @@ -167,7 +190,8 @@ void http_decoder_string_reset(struct http_decoder_string *rstr) { assert(rstr); - switch (rstr->state) { + switch (rstr->state) + { case STRING_STATE_INIT: case STRING_STATE_REFER: case STRING_STATE_CACHE: @@ -183,26 +207,27 @@ void http_decoder_string_reset(struct http_decoder_string *rstr) rstr->state = STRING_STATE_INIT; } - -void http_decoder_string_init(struct http_decoder_string *rstr, - size_t max_cache_size) +void http_decoder_string_init(struct http_decoder_string *rstr, size_t max_cache_size) { rstr->max_cache_size = max_cache_size; } void http_decoder_string_reinit(struct http_decoder_string *rstr) { - if (rstr->state == STRING_STATE_CACHE) { + if (rstr->state == STRING_STATE_CACHE) + { return; } if (rstr->state == STRING_STATE_COMMIT && rstr->cache.iov_base == rstr->commit.iov_base && - rstr->cache.iov_len == rstr->commit.iov_len) { + rstr->cache.iov_len == rstr->commit.iov_len) + { return; } - if (rstr->cache.iov_base != NULL) { + if (rstr->cache.iov_base != NULL) + { FREE(rstr->cache.iov_base); rstr->cache.iov_len = 0; } @@ -213,7 +238,7 @@ void http_decoder_string_reinit(struct http_decoder_string *rstr) rstr->commit.iov_base = NULL; rstr->commit.iov_len = 0; rstr->state = STRING_STATE_INIT; -#endif +#endif } enum string_state http_decoder_string_state(const struct http_decoder_string *rstr) @@ -223,14 +248,18 @@ enum string_state http_decoder_string_state(const struct http_decoder_string *rs int http_decoder_string_get(const struct http_decoder_string *rstr, hstring *out) { - if (NULL == rstr || NULL == out) { + if (NULL == rstr || NULL == out) + { return -1; } - if (http_decoder_string_state(rstr) == STRING_STATE_COMMIT) { + if (http_decoder_string_state(rstr) == STRING_STATE_COMMIT) + { out->iov_base = rstr->commit.iov_base; out->iov_len = rstr->commit.iov_len; - } else { + } + else + { out->iov_base = NULL; out->iov_len = 0; } @@ -240,7 +269,8 @@ int http_decoder_string_get(const struct http_decoder_string *rstr, hstring *out void http_decoder_string_dump(struct http_decoder_string *rstr, const char *desc) { - if (NULL == rstr) { + if (NULL == rstr) + { return; } diff --git a/decoders/http/http_decoder_string.h b/decoders/http/http_decoder_string.h index 3b25732..006794c 100644 --- a/decoders/http/http_decoder_string.h +++ b/decoders/http/http_decoder_string.h @@ -1,5 +1,4 @@ -#ifndef _HTTP_DECODER_STRING_H_ -#define _HTTP_DECODER_STRING_H_ +#pragma once #include "stellar/http.h" @@ -71,4 +70,4 @@ enum string_state http_decoder_string_state(const struct http_decoder_string *rs int http_decoder_string_get(const struct http_decoder_string *rstr, hstring *out); void http_decoder_string_dump(struct http_decoder_string *rstr, const char *desc); -#endif \ No newline at end of file + \ No newline at end of file diff --git a/decoders/http/http_decoder_table.cpp b/decoders/http/http_decoder_table.cpp index b58154f..bdf15d0 100644 --- a/decoders/http/http_decoder_table.cpp +++ b/decoders/http/http_decoder_table.cpp @@ -1,7 +1,7 @@ #include #include #include -#include "http_decoder_inc.h" +#include "http_decoder_private.h" #define INIT_HEADER_CNT 16 #define MAX_URI_CACHE_SIZE 2048 @@ -11,12 +11,14 @@ #define MAX_HEADER_KEY_CACHE_SIZE 4096 #define MAX_HEADER_VALUE_CACHE_SIZE 4096 -struct http_decoder_header { +struct http_decoder_header +{ struct http_decoder_string key; struct http_decoder_string val; }; -struct http_decoder_table { +struct http_decoder_table +{ struct http_decoder_string uri; struct http_decoder_string status; struct http_decoder_string method; @@ -26,15 +28,16 @@ struct http_decoder_table { nmx_pool_t *ref_mempool; int header_complete; // flag for all headers parsed completely size_t header_cnt; - size_t header_index; //current parsing header - size_t header_iter; //plugins iterate cursor - size_t commit_header_index; //pushed to plugins, whether has called http_message_header_next() + size_t header_index; // current parsing header + size_t header_iter; // plugins iterate cursor + size_t commit_header_index; // pushed to plugins, whether has called http_message_header_next() struct http_decoder_header *headers; }; static void http_decoder_table_init(struct http_decoder_table *table) { - if (NULL == table) { + if (NULL == table) + { return; } @@ -46,12 +49,13 @@ static void http_decoder_table_init(struct http_decoder_table *table) http_decoder_string_init(&table->method, MAX_METHOD_CACHE_SIZE); http_decoder_string_init(&table->version, MAX_METHOD_CACHE_SIZE); - for (size_t i = 0; i < table->header_cnt; i++) { + for (size_t i = 0; i < table->header_cnt; i++) + { header = &table->headers[i]; http_decoder_string_init(&header->key, MAX_HEADER_KEY_CACHE_SIZE); http_decoder_string_init(&header->val, MAX_HEADER_VALUE_CACHE_SIZE); } - + http_decoder_string_init(&table->body, 0); } @@ -73,32 +77,42 @@ struct http_decoder_table *http_decoder_table_new(nmx_pool_t *mempool) void http_decoder_table_free(struct http_decoder_table *table) { - if (NULL == table) { + if (NULL == table) + { return; } - if (table->uri.cache.iov_base != NULL) { + if (table->uri.cache.iov_base != NULL) + { FREE(table->uri.cache.iov_base); } - if (table->status.cache.iov_base != NULL) { + if (table->status.cache.iov_base != NULL) + { FREE(table->status.cache.iov_base); } - if (table->method.cache.iov_base != NULL) { + if (table->method.cache.iov_base != NULL) + { FREE(table->method.cache.iov_base); } - if (table->version.cache.iov_base != NULL) { + if (table->version.cache.iov_base != NULL) + { FREE(table->version.cache.iov_base); } - if (table->body.cache.iov_base != NULL) { + if (table->body.cache.iov_base != NULL) + { FREE(table->body.cache.iov_base); } - if (table->headers != NULL) { - for (size_t i = 0; i < table->header_cnt; i++) { - if (table->headers[i].key.cache.iov_base != NULL) { + if (table->headers != NULL) + { + for (size_t i = 0; i < table->header_cnt; i++) + { + if (table->headers[i].key.cache.iov_base != NULL) + { FREE(table->headers[i].key.cache.iov_base); } - if (table->headers[i].val.cache.iov_base != NULL) { + if (table->headers[i].val.cache.iov_base != NULL) + { FREE(table->headers[i].val.cache.iov_base); } } @@ -109,17 +123,18 @@ void http_decoder_table_free(struct http_decoder_table *table) MEMPOOL_FREE(table->ref_mempool, table); } -enum string_state -http_decoder_table_state(struct http_decoder_table *table, enum http_item type) +enum string_state http_decoder_table_state(struct http_decoder_table *table, enum http_item type) { - if (NULL == table) { + if (NULL == table) + { return STRING_STATE_INIT; } struct http_decoder_header *header = NULL; enum string_state state = STRING_STATE_INIT; assert(table); - switch (type) { + switch (type) + { case HTTP_ITEM_URI: state = http_decoder_string_state(&table->uri); break; @@ -153,17 +168,18 @@ http_decoder_table_state(struct http_decoder_table *table, enum http_item type) return state; } -void http_decoder_table_refer(struct http_decoder_table *table, enum http_item type, - const char *at, size_t len) +void http_decoder_table_refer(struct http_decoder_table *table, enum http_item type, const char *at, size_t len) { - if (NULL == table) { + if (NULL == table) + { return; } struct http_decoder_header *header = NULL; assert(table); - switch (type) { + switch (type) + { case HTTP_ITEM_URI: http_decoder_string_refer(&table->uri, at, len); break; @@ -197,14 +213,16 @@ void http_decoder_table_refer(struct http_decoder_table *table, enum http_item t void http_decoder_table_cache(struct http_decoder_table *table, enum http_item type) { - if (NULL == table) { + if (NULL == table) + { return; } struct http_decoder_header *header = NULL; assert(table); - switch (type) { + switch (type) + { case HTTP_ITEM_URI: http_decoder_string_cache(&table->uri); break; @@ -238,7 +256,8 @@ void http_decoder_table_cache(struct http_decoder_table *table, enum http_item t void http_decoder_table_commit(struct http_decoder_table *table, enum http_item type) { - if (NULL == table) { + if (NULL == table) + { return; } @@ -246,7 +265,8 @@ void http_decoder_table_commit(struct http_decoder_table *table, enum http_item struct http_decoder_header *header = NULL; assert(table); - switch (type) { + switch (type) + { case HTTP_ITEM_URI: http_decoder_string_commit(&table->uri); break; @@ -268,20 +288,23 @@ void http_decoder_table_commit(struct http_decoder_table *table, enum http_item header = &table->headers[table->header_index]; http_decoder_string_commit(&header->val); // inc index - if ((table->header_index + 1) >= table->header_cnt) { + if ((table->header_index + 1) >= table->header_cnt) + { struct http_decoder_header *old_headers = table->headers; table->headers = MEMPOOL_CALLOC(table->ref_mempool, struct http_decoder_header, table->header_cnt * 2); table->header_cnt *= 2; - for (i = 0; i <= table->header_index; i++) { + for (i = 0; i <= table->header_index; i++) + { table->headers[i] = old_headers[i]; } MEMPOOL_FREE(table->ref_mempool, old_headers); - for (i = table->header_index + 1; i < table->header_cnt; i++) { + for (i = table->header_index + 1; i < table->header_cnt; i++) + { header = &table->headers[i]; memset(header, 0, sizeof(struct http_decoder_header)); http_decoder_string_init(&header->key, MAX_HEADER_KEY_CACHE_SIZE); @@ -301,14 +324,16 @@ void http_decoder_table_commit(struct http_decoder_table *table, enum http_item void http_decoder_table_reset(struct http_decoder_table *table, enum http_item type) { - if (NULL == table) { + if (NULL == table) + { return; } struct http_decoder_header *header = NULL; assert(table); - switch (type) { + switch (type) + { case HTTP_ITEM_URI: http_decoder_string_reset(&table->uri); break; @@ -342,14 +367,15 @@ void http_decoder_table_reinit(struct http_decoder_table *table) { assert(table); struct http_decoder_header *header = NULL; - + http_decoder_string_reinit(&table->uri); http_decoder_string_reinit(&table->status); http_decoder_string_reinit(&table->method); http_decoder_string_reinit(&table->version); // for (size_t i = 0; i < table->header_iter; i++) { - for (size_t i = 0; i < table->commit_header_index; i++) { - //todo, reset header_index, avoid realloc headers as much as possible + for (size_t i = 0; i < table->commit_header_index; i++) + { + // todo, reset header_index, avoid realloc headers as much as possible header = &table->headers[i]; http_decoder_string_reinit(&header->key); http_decoder_string_reinit(&header->val); @@ -360,7 +386,8 @@ void http_decoder_table_reinit(struct http_decoder_table *table) void http_decoder_table_dump(struct http_decoder_table *table) { - if (NULL == table) { + if (NULL == table) + { return; } @@ -370,9 +397,11 @@ void http_decoder_table_dump(struct http_decoder_table *table) http_decoder_string_dump(&table->version, "version"); http_decoder_string_dump(&table->body, "body"); - for (size_t i = 0; i < table->header_cnt; i++) { + for (size_t i = 0; i < table->header_cnt; i++) + { struct http_decoder_header *header = &table->headers[i]; - if (NULL == header) { + if (NULL == header) + { continue; } @@ -383,7 +412,8 @@ void http_decoder_table_dump(struct http_decoder_table *table) int http_decoder_table_get_uri(const struct http_decoder_table *table, hstring *out) { - if (NULL == table || NULL == out) { + if (NULL == table || NULL == out) + { return -1; } return http_decoder_string_get(&table->uri, out); @@ -391,7 +421,8 @@ int http_decoder_table_get_uri(const struct http_decoder_table *table, hstring * int http_decoder_table_get_method(const struct http_decoder_table *table, hstring *out) { - if (NULL == table || NULL == out) { + if (NULL == table || NULL == out) + { return -1; } return http_decoder_string_get(&table->method, out); @@ -399,7 +430,8 @@ int http_decoder_table_get_method(const struct http_decoder_table *table, hstrin int http_decoder_table_get_status(const struct http_decoder_table *table, hstring *out) { - if (NULL == table || NULL == out) { + if (NULL == table || NULL == out) + { return -1; } return http_decoder_string_get(&table->status, out); @@ -407,7 +439,8 @@ int http_decoder_table_get_status(const struct http_decoder_table *table, hstrin int http_decoder_table_get_version(const struct http_decoder_table *table, hstring *out) { - if (NULL == table || NULL == out) { + if (NULL == table || NULL == out) + { return -1; } return http_decoder_string_get(&table->version, out); @@ -415,7 +448,8 @@ int http_decoder_table_get_version(const struct http_decoder_table *table, hstri int http_decoder_table_get_body(const struct http_decoder_table *table, hstring *out) { - if (NULL == table || NULL == out) { + if (NULL == table || NULL == out) + { return -1; } return http_decoder_string_get(&table->body, out); @@ -424,19 +458,23 @@ int http_decoder_table_get_body(const struct http_decoder_table *table, hstring int http_decoder_table_get_header(const struct http_decoder_table *table, const hstring *key, struct http_header *hdr_result) { - for (size_t i = 0; i < table->header_cnt; i++) { + for (size_t i = 0; i < table->header_cnt; i++) + { const struct http_decoder_header *tmp_header = &table->headers[i]; - if (tmp_header->key.commit.iov_len != key->iov_len) { + if (tmp_header->key.commit.iov_len != key->iov_len) + { continue; } if (http_decoder_string_state(&tmp_header->key) == STRING_STATE_COMMIT && - http_decoder_string_state(&tmp_header->val) == STRING_STATE_COMMIT) { + http_decoder_string_state(&tmp_header->val) == STRING_STATE_COMMIT) + { hstring tmp_key; http_decoder_string_get(&tmp_header->key, &tmp_key); if (tmp_key.iov_len == key->iov_len && - (0 == strncasecmp((char *)tmp_key.iov_base, (char *)key->iov_base, key->iov_len))) { + (0 == strncasecmp((char *)tmp_key.iov_base, (char *)key->iov_base, key->iov_len))) + { http_decoder_string_get(&tmp_header->key, &hdr_result->key); http_decoder_string_get(&tmp_header->val, &hdr_result->val); return 0; @@ -446,20 +484,23 @@ int http_decoder_table_get_header(const struct http_decoder_table *table, const return -1; } -int http_decoder_table_iter_header(struct http_decoder_table *table, - struct http_header *hdr) +int http_decoder_table_iter_header(struct http_decoder_table *table, struct http_header *hdr) { - if (NULL == table || NULL == hdr) { + if (NULL == table || NULL == hdr) + { return -1; } - if (table->header_iter >= table->header_cnt) { + if (table->header_iter >= table->header_cnt) + { return -1; } struct http_decoder_header *tmp_header = &table->headers[table->header_iter]; - if (tmp_header != NULL) { + if (tmp_header != NULL) + { if (http_decoder_string_state(&tmp_header->key) == STRING_STATE_COMMIT && - http_decoder_string_state(&tmp_header->val) == STRING_STATE_COMMIT) { + http_decoder_string_state(&tmp_header->val) == STRING_STATE_COMMIT) + { http_decoder_string_get(&tmp_header->key, &hdr->key); http_decoder_string_get(&tmp_header->val, &hdr->val); @@ -485,14 +526,15 @@ int http_decoder_table_reset_header_iter(struct http_decoder_table *table) int http_decoder_table_has_parsed_header(struct http_decoder_table *table) { // if (NULL == table || (table->header_iter == table->header_index)) { - if (NULL == table || (table->commit_header_index == table->header_index)) { + if (NULL == table || (table->commit_header_index == table->header_index)) + { return 0; } const struct http_decoder_header *tmp_header = &table->headers[table->header_iter]; - if (http_decoder_string_state(&tmp_header->key) == STRING_STATE_COMMIT - && http_decoder_string_state(&tmp_header->val) == STRING_STATE_COMMIT) { + if (http_decoder_string_state(&tmp_header->key) == STRING_STATE_COMMIT && http_decoder_string_state(&tmp_header->val) == STRING_STATE_COMMIT) + { return 1; } @@ -501,7 +543,8 @@ int http_decoder_table_has_parsed_header(struct http_decoder_table *table) int http_decoder_table_header_complete(struct http_decoder_table *table) { - if (NULL == table) { + if (NULL == table) + { return -1; } return table->header_complete; @@ -509,7 +552,8 @@ int http_decoder_table_header_complete(struct http_decoder_table *table) void http_decoder_table_set_header_complete(struct http_decoder_table *table) { - if (NULL == table) { + if (NULL == table) + { return; } table->header_complete = 1; @@ -517,7 +561,8 @@ void http_decoder_table_set_header_complete(struct http_decoder_table *table) void http_decoder_table_reset_header_complete(struct http_decoder_table *table) { - if (NULL == table) { + if (NULL == table) + { return; } table->header_complete = 0; diff --git a/decoders/http/http_decoder_table.h b/decoders/http/http_decoder_table.h index bbc6956..d32f6be 100644 --- a/decoders/http/http_decoder_table.h +++ b/decoders/http/http_decoder_table.h @@ -1,11 +1,11 @@ -#ifndef _HTTP_DECODER_TABLE_H_ -#define _HTTP_DECODER_TABLE_H_ +#pragma once #include #include "stellar/http.h" -#include "http_decoder_inc.h" +#include "http_decoder_private.h" #include "http_decoder_string.h" -enum http_item { +enum http_item +{ HTTP_ITEM_URI = 0x01, HTTP_ITEM_STATUS = 0x02, HTTP_ITEM_METHOD = 0x03, @@ -55,9 +55,9 @@ int http_decoder_table_iter_header(struct http_decoder_table *table, int http_decoder_table_reset_header_iter(struct http_decoder_table *table); /** * @brief Is there a parsed header - * + * * @retval yes(1) no(0) -*/ + */ int http_decoder_table_has_parsed_header(struct http_decoder_table *table); /** @@ -69,7 +69,7 @@ int http_decoder_table_header_complete(struct http_decoder_table *table); /** * @brief set flag for headers parsed completely -*/ + */ void http_decoder_table_set_header_complete(struct http_decoder_table *table); void http_decoder_table_reset_header_complete(struct http_decoder_table *table); @@ -77,4 +77,3 @@ void http_decoder_table_reset_header_complete(struct http_decoder_table *table); void http_decoder_table_update_commit_index(struct http_decoder_table *table); int http_decoder_table_get_total_parsed_header(struct http_decoder_table *table); -#endif \ No newline at end of file diff --git a/decoders/http/http_decoder_tunnel.cpp b/decoders/http/http_decoder_tunnel.cpp index 42f100a..cf5a573 100644 --- a/decoders/http/http_decoder_tunnel.cpp +++ b/decoders/http/http_decoder_tunnel.cpp @@ -3,7 +3,7 @@ #include #include #include -#include "http_decoder_inc.h" +#include "http_decoder_private.h" #include "llhttp.h" struct http_tunnel_message @@ -12,28 +12,32 @@ struct http_tunnel_message hstring tunnel_payload; }; - int httpd_tunnel_identify(struct http_decoder_env *httpd_env, int curdir, struct http_decoder_half_data *hfdata) { - if(0 == httpd_env->hd_cfg.proxy_enable){ + if (0 == httpd_env->hd_cfg.proxy_enable) + { return 0; } - if(FLOW_DIRECTION_C2S == curdir){ + if (FLOW_DIRECTION_C2S == curdir) + { struct http_request_line reqline = {}; http_decoder_half_data_get_request_line(hfdata, &reqline); - if(0 == strncasecmp_safe("CONNECT", (char *)reqline.method.iov_base, - 7, reqline.method.iov_len)){ + if (0 == strncasecmp_safe("CONNECT", (char *)reqline.method.iov_base, + 7, reqline.method.iov_len)) + { return 1; } - }else{ + } + else + { struct http_response_line resline = {}; http_decoder_half_data_get_response_line(hfdata, &resline); - if(resline.status_code == HTTP_STATUS_OK - && 0 == strncasecmp_safe("Connection established", (char *)resline.status.iov_base, - strlen("Connection established"), resline.status.iov_len)){ + if (resline.status_code == HTTP_STATUS_OK && 0 == strncasecmp_safe("Connection established", (char *)resline.status.iov_base, + strlen("Connection established"), resline.status.iov_len)) + { return 1; - } + } } return 0; @@ -41,15 +45,17 @@ int httpd_tunnel_identify(struct http_decoder_env *httpd_env, int curdir, struct int httpd_is_tunnel_session(const struct http_decoder_env *httpd_env, const struct http_decoder_exdata *ex_data) { - if(0 == httpd_env->hd_cfg.proxy_enable){ + if (0 == httpd_env->hd_cfg.proxy_enable) + { return 0; - } + } return (ex_data && ex_data->tunnel_state != HTTP_TUN_NON); } int httpd_in_tunnel_transmitting(const struct http_decoder_env *httpd_env, struct http_decoder_exdata *ex_data) { - if(0 == httpd_env->hd_cfg.proxy_enable){ + if (0 == httpd_env->hd_cfg.proxy_enable) + { return 0; } return (ex_data && ex_data->tunnel_state >= HTTP_TUN_INNER_STARTING); @@ -57,10 +63,12 @@ int httpd_in_tunnel_transmitting(const struct http_decoder_env *httpd_env, struc enum http_tunnel_message_type httpd_tunnel_state_to_msg(const struct http_decoder_exdata *ex_data) { - if(ex_data->tunnel_state == HTTP_TUN_INNER_STARTING){ + if (ex_data->tunnel_state == HTTP_TUN_INNER_STARTING) + { return HTTP_TUNNEL_OPENING; } - if(ex_data->tunnel_state == HTTP_TUN_INNER_TRANS){ + if (ex_data->tunnel_state == HTTP_TUN_INNER_TRANS) + { return HTTP_TUNNEL_ACTIVE; } return HTTP_TUNNEL_MSG_MAX; @@ -68,7 +76,8 @@ enum http_tunnel_message_type httpd_tunnel_state_to_msg(const struct http_decode void httpd_tunnel_state_update(struct http_decoder_exdata *ex_data) { - if(ex_data->tunnel_state == HTTP_TUN_INNER_STARTING){ + if (ex_data->tunnel_state == HTTP_TUN_INNER_STARTING) + { ex_data->tunnel_state = HTTP_TUN_INNER_TRANS; } } @@ -86,21 +95,21 @@ void http_decoder_push_tunnel_data(struct session *sess, const struct http_decod extern "C" { #endif -void http_tunnel_message_get_payload(const struct http_tunnel_message *tmsg, - hstring *tunnel_payload) -{ - if (unlikely(NULL == tmsg || tunnel_payload == NULL)) + void http_tunnel_message_get_payload(const struct http_tunnel_message *tmsg, + hstring *tunnel_payload) { - return; + if (unlikely(NULL == tmsg || tunnel_payload == NULL)) + { + return; + } + tunnel_payload->iov_base = tmsg->tunnel_payload.iov_base; + tunnel_payload->iov_len = tmsg->tunnel_payload.iov_len; } - tunnel_payload->iov_base = tmsg->tunnel_payload.iov_base; - tunnel_payload->iov_len = tmsg->tunnel_payload.iov_len; -} -enum http_tunnel_message_type http_tunnel_message_type_get(const struct http_tunnel_message *tmsg) -{ - return tmsg->type; -} + enum http_tunnel_message_type http_tunnel_message_type_get(const struct http_tunnel_message *tmsg) + { + return tmsg->type; + } #ifdef __cplusplus } diff --git a/decoders/http/http_decoder_tunnel.h b/decoders/http/http_decoder_tunnel.h index b90e402..52882e5 100644 --- a/decoders/http/http_decoder_tunnel.h +++ b/decoders/http/http_decoder_tunnel.h @@ -1,23 +1,25 @@ -#pragma once -#include "http_decoder_inc.h" +#pragma once +#include "http_decoder_private.h" #include "http_decoder_half.h" -enum http_tunnel_state{ - HTTP_TUN_NON = 0, // init, or not tunnel session - HTTP_TUN_C2S_HDR_START, //CONNECT ... - HTTP_TUN_C2S_END, //CONNECT request end - HTTP_TUN_S2C_START, // HTTP 200 connet established - HTTP_TUN_INNER_STARTING, // http inner tunnel protocol starting - HTTP_TUN_INNER_TRANS, // http inner tunnel protocol transmitting +enum http_tunnel_state +{ + HTTP_TUN_NON = 0, // init, or not tunnel session + HTTP_TUN_C2S_HDR_START, // CONNECT ... + HTTP_TUN_C2S_END, // CONNECT request end + HTTP_TUN_S2C_START, // HTTP 200 connet established + HTTP_TUN_INNER_STARTING, // http inner tunnel protocol starting + HTTP_TUN_INNER_TRANS, // http inner tunnel protocol transmitting }; /************************************************************ -* HTTP TUNNEL WITH CONNECT METHOD. -*************************************************************/ + * HTTP TUNNEL WITH CONNECT METHOD. + *************************************************************/ struct http_tunnel_message; -#define HTTP_DECODER_TUNNEL_TOPIC "HTTP_DECODER_TUNNEL_MESSAGE" +#define HTTP_DECODER_TUNNEL_TOPIC "HTTP_DECODER_TUNNEL_MESSAGE" -enum http_tunnel_message_type { +enum http_tunnel_message_type +{ HTTP_TUNNEL_OPENING, HTTP_TUNNEL_ACTIVE, HTTP_TUNNEL_CLOSING, @@ -26,7 +28,6 @@ enum http_tunnel_message_type { enum http_tunnel_message_type http_tunnel_message_type_get(const struct http_tunnel_message *tmsg); void http_tunnel_message_get_payload(const struct http_tunnel_message *tmsg, struct iovec *tunnel_payload); - int httpd_tunnel_identify(struct http_decoder_env *httpd_env, int curdir, struct http_decoder_half_data *hfdata); int httpd_is_tunnel_session(const struct http_decoder_env *httpd_env, const struct http_decoder_exdata *ex_data); int httpd_in_tunnel_transmitting(const struct http_decoder_env *httpd_env, struct http_decoder_exdata *ex_data); diff --git a/decoders/http/http_decoder_utils.cpp b/decoders/http/http_decoder_utils.cpp index 93fef81..181d592 100644 --- a/decoders/http/http_decoder_utils.cpp +++ b/decoders/http/http_decoder_utils.cpp @@ -1,7 +1,7 @@ #include #include #include "stellar/http.h" -#include "http_decoder_inc.h" +#include "http_decoder_private.h" char *safe_dup(const char *str, size_t len) { @@ -164,7 +164,8 @@ int http_event_is_req(enum http_event event) return -1; } -int stellar_session_mq_get_topic_id_reliable(struct stellar *st, const char *topic_name, stellar_msg_free_cb_func *msg_free_cb, void *msg_free_arg) +int stellar_session_mq_get_topic_id_reliable(struct stellar *st, const char *topic_name, + stellar_msg_free_cb_func *msg_free_cb, void *msg_free_arg) { int topic_id = stellar_mq_get_topic_id(st, topic_name); if (topic_id < 0) diff --git a/decoders/http/http_decoder_utils.h b/decoders/http/http_decoder_utils.h index 33483cf..54dcd04 100644 --- a/decoders/http/http_decoder_utils.h +++ b/decoders/http/http_decoder_utils.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include #include @@ -29,7 +29,8 @@ int httpd_url_is_encoded(const char *url, size_t len); * Logger ******************************************************************************/ -enum http_decoder_log_level { +enum http_decoder_log_level +{ DEBUG = 0x11, WARN = 0x12, INFO = 0x13, @@ -61,20 +62,19 @@ enum http_decoder_log_level { } #endif - #include struct httpd_session_addr { - uint8_t ipver; /* 4 or 6 */ - uint16_t sport; /* network order */ - uint16_t dport; /* network order */ - union - { + uint8_t ipver; /* 4 or 6 */ + uint16_t sport; /* network order */ + uint16_t dport; /* network order */ + union + { uint32_t saddr4; uint32_t daddr4; - struct in6_addr saddr6; + struct in6_addr saddr6; struct in6_addr daddr6; - }; + }; }; void httpd_session_get_addr(const struct session *sess, struct httpd_session_addr *addr); diff --git a/include/stellar/http.h b/include/stellar/http.h index ba00ab7..3c749ca 100644 --- a/include/stellar/http.h +++ b/include/stellar/http.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #ifdef __cplusplus extern "C" @@ -6,94 +6,98 @@ extern "C" #endif #include -struct http_message; -#define HTTP_DECODER_TOPIC "HTTP_DECODER_MESSAGE" +#define HTTP_DECODER_TOPIC "HTTP_DECODER_MESSAGE" + struct http_message; -enum http_message_type { - HTTP_TRANSACTION_START, + enum http_message_type + { + HTTP_TRANSACTION_START, - HTTP_MESSAGE_REQ_LINE, - HTTP_MESSAGE_REQ_HEADER, - HTTP_MESSAGE_REQ_HEADER_END, - HTTP_MESSAGE_REQ_BODY_START, - HTTP_MESSAGE_REQ_BODY, - HTTP_MESSAGE_REQ_BODY_END, - - HTTP_MESSAGE_RES_LINE, - HTTP_MESSAGE_RES_HEADER, - HTTP_MESSAGE_RES_HEADER_END, - HTTP_MESSAGE_RES_BODY_START, - HTTP_MESSAGE_RES_BODY, - HTTP_MESSAGE_RES_BODY_END, + HTTP_MESSAGE_REQ_LINE, + HTTP_MESSAGE_REQ_HEADER, + HTTP_MESSAGE_REQ_HEADER_END, + HTTP_MESSAGE_REQ_BODY_START, + HTTP_MESSAGE_REQ_BODY, + HTTP_MESSAGE_REQ_BODY_END, - HTTP_TRANSACTION_END, + HTTP_MESSAGE_RES_LINE, + HTTP_MESSAGE_RES_HEADER, + HTTP_MESSAGE_RES_HEADER_END, + HTTP_MESSAGE_RES_BODY_START, + HTTP_MESSAGE_RES_BODY, + HTTP_MESSAGE_RES_BODY_END, - HTTP_MESSAGE_MAX -}; + HTTP_TRANSACTION_END, -struct http_header { - struct iovec key; - struct iovec val; -}; + HTTP_MESSAGE_MAX + }; -struct http_request_line { - struct iovec method; - struct iovec uri; - struct iovec version; - int major_version; - int minor_version; -}; + struct http_header + { + struct iovec key; + struct iovec val; + }; -struct http_response_line { - struct iovec version; - struct iovec status; - int major_version; - int minor_version; - int status_code; -}; + struct http_request_line + { + struct iovec method; + struct iovec uri; + struct iovec version; + int major_version; + int minor_version; + }; -typedef struct iovec hstring; + struct http_response_line + { + struct iovec version; + struct iovec status; + int major_version; + int minor_version; + int status_code; + }; -enum http_message_type http_message_type_get(const struct http_message *msg); + typedef struct iovec hstring; -void http_message_request_line_get0(const struct http_message *msg, struct http_request_line *line); + enum http_message_type http_message_type_get(const struct http_message *msg); -void http_message_response_line_get0(const struct http_message *msg, struct http_response_line *line); + void http_message_request_line_get0(const struct http_message *msg, struct http_request_line *line); -/* -* Pay attention: key->iov_base is case-insensitive. -*/ -void http_message_header_get0(const struct http_message *msg, const struct iovec *key, struct http_header *hdr_result); + void http_message_response_line_get0(const struct http_message *msg, struct http_response_line *line); -/** - * @brief loop reading all headers. - * - * @retval succeed( >= 0) failed(-1) -*/ -int http_message_header_next(const struct http_message *msg, struct http_header *header); + /* + * Pay attention: key->iov_base is case-insensitive. + */ + void http_message_header_get0(const struct http_message *msg, const struct iovec *key, struct http_header *hdr_result); -/** - * @retval succeed( >= 0) failed(-1) -*/ -int http_message_reset_header_iter(struct http_message *msg); + /** + * @brief loop reading all headers. + * + * @retval succeed( >= 0) failed(-1) + */ + int http_message_header_next(const struct http_message *msg, struct http_header *header); -void http_message_raw_body_get0(const struct http_message *msg, struct iovec *body); + /** + * @retval succeed( >= 0) failed(-1) + */ + int http_message_reset_header_iter(struct http_message *msg); -/** - * @brief If the body hasn't been compressed, same as http_message_raw_body_get0(). - * -*/ -void http_message_decompress_body_get0(const struct http_message *msg, struct iovec *body); + void http_message_raw_body_get0(const struct http_message *msg, struct iovec *body); -//raw -void http_message_raw_url_get0(const struct http_message *msg, struct iovec *url); + /** + * @brief If the body hasn't been compressed, same as http_message_raw_body_get0(). + * + */ + void http_message_decompress_body_get0(const struct http_message *msg, struct iovec *body); -void http_message_decoded_url_get0(const struct http_message *msg, struct iovec *url); + // raw + void http_message_raw_url_get0(const struct http_message *msg, struct iovec *url); -/** - * @retval succeed( >= 0) failed(-1) -*/ -int http_message_get_transaction_seq(const struct http_message *msg); + void http_message_decoded_url_get0(const struct http_message *msg, struct iovec *url); + + /** + * @retval succeed( >= 0) failed(-1) + */ + int http_message_get_transaction_seq(const struct http_message *msg); #ifdef __cplusplus } diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index aa22cff..1cb942f 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,7 +1,7 @@ set(SOURCE stellar_config.cpp stellar_stat.cpp stellar_core.cpp) set(LIBRARY session_manager plugin_manager ip_reassembly packet_io packet pthread fieldstat4 toml nmx_pool) -set(PLUGIN http_decoder glimpse_detector) +set(PLUGIN http glimpse_detector) add_library(core STATIC ${SOURCE}) target_link_libraries(core PUBLIC ${LIBRARY}) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a0a7d5b..fa10371 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(packet_inject) add_subdirectory(packet_tool) add_subdirectory(debug_plugin) -#add_subdirectory(glimpse_detector) \ No newline at end of file +#add_subdirectory(glimpse_detector) +#add_subdirectory(decoders/http) diff --git a/test/http_decoder/.gitkeep b/test/decoders/http/.gitkeep similarity index 100% rename from test/http_decoder/.gitkeep rename to test/decoders/http/.gitkeep diff --git a/test/decoders/http/CMakeLists.txt b/test/decoders/http/CMakeLists.txt new file mode 100644 index 0000000..78467f5 --- /dev/null +++ b/test/decoders/http/CMakeLists.txt @@ -0,0 +1,50 @@ +set(DECODER_NAME http) + +aux_source_directory(${PROJECT_SOURCE_DIR}/deps/toml DEPS_SRC) + +add_library(${DECODER_NAME}_test SHARED http_decoder_test_plug.cpp md5.c ${DEPS_SRC}) +add_dependencies(${DECODER_NAME}_test ${DECODER_NAME}) +target_link_libraries(${DECODER_NAME}_test cjson-static) +set_target_properties(${DECODER_NAME}_test PROPERTIES PREFIX "") + +# add_library(${DECODER_NAME}_perf SHARED http_decoder_perf_plug.cpp) +# add_dependencies(${DECODER_NAME}_perf ${DECODER_NAME}) +# set_target_properties(${DECODER_NAME}_perf PROPERTIES PREFIX "") + +set(TEST_RUN_DIR ${CMAKE_BINARY_DIR}/testing) + +include_directories(${CMAKE_SOURCE_DIR}/include) +include_directories(${CMAKE_SOURCE_DIR}/src) +include_directories(${CMAKE_SOURCE_DIR}/deps) +include_directories(/opt/tsg/stellar/include/) +include_directories(/opt/tsg/framework/include/) +include_directories(${CMAKE_BINARY_DIR}/vendor/llhttp/include) +include_directories(${CMAKE_BINARY_DIR}/vendor/cjson/src/cjson/include) +include_directories(${PROJECT_SOURCE_DIR}/decoders/http) +include_directories(${PROJECT_SOURCE_DIR}/include/stellar) + +aux_source_directory(${PROJECT_SOURCE_DIR}/deps/mempool PERF_TEST_DEP_SRC) +aux_source_directory(${PROJECT_SOURCE_DIR}/deps/toml PERF_TEST_DEP_SRC) +aux_source_directory(${PROJECT_SOURCE_DIR}/src PERF_TEST_DEP_SRC) + +add_executable(gtest_http http_decoder_gtest.cpp ${PROJECT_SOURCE_DIR}/decoders/http/http_decoder_utils.cpp) +target_link_libraries(gtest_http gtest stellar_devel) + +add_executable(http_test_main plugin_test_main.cpp) +set_target_properties(http_test_main + PROPERTIES + LINK_OPTIONS + "-rdynamic" + ) +set_target_properties(http_test_main + PROPERTIES + LINK_FLAGS + "-rdynamic" + ) +set(LINK_FLAGS "-rdynamic") +target_link_libraries(http_test_main gtest cjson-static stellar_devel) + +add_subdirectory(test_based_on_stellar) + +include(GoogleTest) +gtest_discover_tests(gtest_http) diff --git a/test/http_decoder/base64.c b/test/decoders/http/base64.c similarity index 100% rename from test/http_decoder/base64.c rename to test/decoders/http/base64.c diff --git a/test/http_decoder/base64.h b/test/decoders/http/base64.h similarity index 100% rename from test/http_decoder/base64.h rename to test/decoders/http/base64.h diff --git a/test/http_decoder/http_decoder_gtest.cpp b/test/decoders/http/http_decoder_gtest.cpp similarity index 92% rename from test/http_decoder/http_decoder_gtest.cpp rename to test/decoders/http/http_decoder_gtest.cpp index c8ad653..68f275f 100644 --- a/test/http_decoder/http_decoder_gtest.cpp +++ b/test/decoders/http/http_decoder_gtest.cpp @@ -1,11 +1,11 @@ #include #include #include -#include "http_decoder.h" -#include "http_decoder_inc.h" +#include "http.h" +#include "http_decoder_private.h" void httpd_url_decode(const char *string, size_t length, char *ostring, size_t *olen); -TEST(url_decoder, none) +TEST(http_url_decoder, none) { char decode_url_buf[2048]; size_t decode_url_len = sizeof(decode_url_buf); @@ -16,7 +16,7 @@ TEST(url_decoder, none) EXPECT_EQ(decode_url_len, strlen("https://docs.geedge.net/#all-updates")); } -TEST(url_decoder, simple) +TEST(http_url_decoder, simple) { char decode_url_buf[2048]; size_t decode_url_len = sizeof(decode_url_buf); @@ -34,7 +34,7 @@ TEST(url_decoder, simple) EXPECT_EQ(decode_url_len, sizeof(expect_result)-1); } -TEST(url_decoder, chinese1) +TEST(http_url_decoder, chinese1) { char decode_url_buf[2048]; size_t decode_url_len = sizeof(decode_url_buf); @@ -45,7 +45,7 @@ TEST(url_decoder, chinese1) EXPECT_EQ(decode_url_len, strlen("http://www.baidu.com/\xE6\xB5\x8B\xE8\xAF\x95\xE4\xB8\xAD\xE6\x96\x87\xE8\xA7\xA3\xE7\xA0\x81")); } -TEST(url_decoder, chinese2) +TEST(http_url_decoder, chinese2) { char decode_url_buf[2048]; size_t decode_url_len = sizeof(decode_url_buf); diff --git a/test/http_decoder/http_decoder_gtest.h b/test/decoders/http/http_decoder_gtest.h similarity index 98% rename from test/http_decoder/http_decoder_gtest.h rename to test/decoders/http/http_decoder_gtest.h index a38e6f4..eabae77 100644 --- a/test/http_decoder/http_decoder_gtest.h +++ b/test/decoders/http/http_decoder_gtest.h @@ -10,7 +10,7 @@ extern "C" #ifdef __cplusplus } #endif -#include "http_decoder.h" +#include "http.h" #include "md5.h" #include #include @@ -47,6 +47,7 @@ extern "C" #define EX_DATA_MAX_SIZE 10 #define PIPELINE_MAX_NUM 8 + #define GTEST_FIX_PAYLOAD_CSTR "" #define GTEST_FIX_PAYLOAD_MD5 "e91e072f772737c7a45013cc3b1a916c" @@ -58,6 +59,7 @@ extern "C" #define GTEST_HTTP_RAW_PAYLOAD_MD5_NAME "__X_HTTP_RAW_PAYLOAD_MD5" #define GTEST_HTTP_DECOMPRESS_PAYLOAD_MD5_NAME "__X_HTTP_DECOMPRESS_PAYLOAD_MD5" + struct stellar *stellar_init(void); void stellar_destroy(struct stellar *st); int stellar_load_plugin(struct stellar *st, void *(plugin_init_cb)(struct stellar *st)); diff --git a/test/http_decoder/http_decoder_perf_main.cpp b/test/decoders/http/http_decoder_perf_main.cpp similarity index 100% rename from test/http_decoder/http_decoder_perf_main.cpp rename to test/decoders/http/http_decoder_perf_main.cpp diff --git a/test/http_decoder/http_decoder_perf_plug.cpp b/test/decoders/http/http_decoder_perf_plug.cpp similarity index 98% rename from test/http_decoder/http_decoder_perf_plug.cpp rename to test/decoders/http/http_decoder_perf_plug.cpp index 739e70f..338acaa 100644 --- a/test/http_decoder/http_decoder_perf_plug.cpp +++ b/test/decoders/http/http_decoder_perf_plug.cpp @@ -1,4 +1,4 @@ -#include "http_decoder.h" +#include "http.h" #include #include #include @@ -8,7 +8,7 @@ #ifdef __cplusplus extern "C" { -#include "http_decoder_inc.h" +#include "http_decoder_private.h" #include "cJSON.h" } #endif diff --git a/test/http_decoder/http_decoder_test_plug.cpp b/test/decoders/http/http_decoder_test_plug.cpp similarity index 94% rename from test/http_decoder/http_decoder_test_plug.cpp rename to test/decoders/http/http_decoder_test_plug.cpp index 4c1dd0f..86be09f 100644 --- a/test/http_decoder/http_decoder_test_plug.cpp +++ b/test/decoders/http/http_decoder_test_plug.cpp @@ -4,8 +4,8 @@ #include #include -#include "http_decoder.h" -#include "http_decoder_inc.h" +#include "http.h" +#include "http_decoder_private.h" #ifdef __cplusplus extern "C" @@ -133,6 +133,7 @@ void output_http_body(hstring *body, int decompress_flag) static void append_http_payload(struct session *sess, struct gtest_plug_exdata_t *gtest_plug_exdata, enum payload_compress_mode mode, const hstring *body, enum http_transaction_type type) { + (void)sess; if (NULL == body->iov_base || 0 == body->iov_len) { return; @@ -206,8 +207,8 @@ void http_header_to_json(cJSON *ctx, struct http_header *header) else { // ctx already has the key, so rename key by key%d - char new_key[MAX_KEY_STR_LEN] = {0}; - sprintf(new_key, "%s%d", key, g_header_count++); + char new_key[header->val.iov_len + 64] = {0}; + snprintf(new_key,sizeof(new_key), "%s%d", key, g_header_count++); http_field_to_json(ctx, new_key, (char *)header->val.iov_base, header->val.iov_len); } } @@ -261,9 +262,12 @@ static void commit_payload_md5sum(cJSON *last_jnode, struct gtest_plug_exdata_t for (int i = 0; i < 16; i++) sprintf((char *)md5_result_cstr + 2 * i, "%02x", md5_result_bin[i]); md5_result_cstr[32] = '\0'; - if(mode == PAYLOAD_RAW){ + if (mode == PAYLOAD_RAW) + { cJSON_AddStringToObject(last_jnode, GTEST_HTTP_RAW_PAYLOAD_MD5_NAME, (char *)md5_result_cstr); - }else{ + } + else + { cJSON_AddStringToObject(last_jnode, GTEST_HTTP_DECOMPRESS_PAYLOAD_MD5_NAME, (char *)md5_result_cstr); } FREE(gtest_plug_exdata->payload_md5ctx[mode][type]); @@ -334,7 +338,6 @@ static int get_gtest_plug_entry(const char *cfg_path, char *entry_name, int max_ return -1; } - int ret = 0; char errbuf[256] = {0}; toml_table_t *root = toml_parse_file(fp, errbuf, sizeof(errbuf)); @@ -387,10 +390,13 @@ static void set_gtest_plug_entry(const char *entry_name) extern "C" void http_decoder_test_entry(struct session *sess, int topic_id, const void *raw_msg, void *no_use_ctx, void *plugin_env) { - struct http_request_line req_line = {0}; - struct http_response_line res_line = {0}; - struct http_header header = {0}; - hstring body = {0}; + (void)topic_id; + (void)no_use_ctx; + (void)plugin_env; + struct http_request_line req_line = {}; + struct http_response_line res_line = {}; + struct http_header header = {}; + hstring body = {}; struct http_message *msg = (struct http_message *)raw_msg; enum http_message_type msg_type = http_message_type_get(msg); @@ -401,14 +407,14 @@ extern "C" void http_decoder_test_entry(struct session *sess, int topic_id, cons session_exdata_set(sess, g_exdata_idx, gtest_plug_exdata); } - if (http_message_type_is_req(sess, msg_type)) - { - cJSON *json = gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ]; - } - else - { - cJSON *json = gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES]; - } + // if (http_message_type_is_req(sess, msg_type)) + // { + // cJSON *json = gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_REQ]; + // } + // else + // { + // cJSON *json = gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_RES]; + // } http_decoder_test_update_session_tuple4(sess, gtest_plug_exdata); @@ -485,6 +491,8 @@ extern "C" void http_decoder_test_entry(struct session *sess, int topic_id, cons void http_decoder_test_exdata_free(int idx, void *ex_ptr, void *arg) { + (void)idx; + (void)arg; if (ex_ptr != NULL) { struct gtest_plug_exdata_t *gtest_plug_exdata = (struct gtest_plug_exdata_t *)ex_ptr; @@ -500,16 +508,19 @@ void http_decoder_test_exdata_free(int idx, void *ex_ptr, void *arg) } } -static int update_config_file(const char *filename, const char *key, const char *value) -{ - char cmd_buf[1024] = {}; - snprintf(cmd_buf, 1024, "sed 's/^[ \t]*%s=.*/%s=%s/g' -i %s", key, key, value, filename); - int ret = system(cmd_buf); - return ret; -} +// static int update_config_file(const char *filename, const char *key, const char *value) +// { +// char cmd_buf[1024] = {}; +// snprintf(cmd_buf, 1024, "sed 's/^[ \t]*%s=.*/%s=%s/g' -i %s", key, key, value, filename); +// int ret = system(cmd_buf); +// return ret; +// } extern "C" void http_decoder_test_state_entry(struct session *sess, int topic_id, const void *raw_msg, void *no_use_ctx, void *plugin_env) { + (void)topic_id; + (void)no_use_ctx; + (void)plugin_env; static int msg_index = 0; char msg_index_name[64] = {}; char msg_index_value[64] = {}; @@ -568,6 +579,9 @@ extern "C" void http_decoder_test_state_entry(struct session *sess, int topic_id extern "C" void http_decoder_tunnel_entry(struct session *sess, int topic_id, const void *raw_msg, void *no_use_ctx, void *plugin_env) { + (void)topic_id; + (void)no_use_ctx; + (void)plugin_env; struct gtest_plug_exdata_t *gtest_plug_exdata; enum http_tunnel_message_type tmsg_type = http_tunnel_message_type_get((const struct http_tunnel_message *)raw_msg); static size_t req_payload_block = 0, req_payload_size = 0; @@ -590,7 +604,7 @@ extern "C" void http_decoder_tunnel_entry(struct session *sess, int topic_id, co cJSON_AddStringToObject(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_SESSION], GTEST_HTTP_TUPLE4_NAME, human_addr_cstr); commit_test_result_json(gtest_plug_exdata->result_jnode[HTTP_TRANSACTION_SESSION], "TUNNEL_NEW"); } - // OPENING state has payload, go on + break; case HTTP_TUNNEL_ACTIVE: { diff --git a/test/http_decoder/md5.c b/test/decoders/http/md5.c similarity index 96% rename from test/http_decoder/md5.c rename to test/decoders/http/md5.c index 13a5d16..3df1eb5 100644 --- a/test/http_decoder/md5.c +++ b/test/decoders/http/md5.c @@ -346,7 +346,7 @@ Rotation is separate from addition to prevent recomputation. */ MD5Init(&context); MD5Update(&context, raw_data, raw_data_len); - MD5Final(result, &context); + MD5Final((unsigned char *)result, &context); return result; } diff --git a/test/http_decoder/md5.h b/test/decoders/http/md5.h similarity index 100% rename from test/http_decoder/md5.h rename to test/decoders/http/md5.h diff --git a/test/http_decoder/test_based_on_stellar/plugin_test_main.cpp b/test/decoders/http/plugin_test_main.cpp similarity index 99% rename from test/http_decoder/test_based_on_stellar/plugin_test_main.cpp rename to test/decoders/http/plugin_test_main.cpp index accec2d..a94c692 100644 --- a/test/http_decoder/test_based_on_stellar/plugin_test_main.cpp +++ b/test/decoders/http/plugin_test_main.cpp @@ -1,4 +1,3 @@ -#include "stream.h" #include "cJSON.h" #include #include @@ -19,13 +18,13 @@ extern "C" #ifdef IGNORE_PRINTF #define printf(fmt, ...) (0) #endif - static cJSON *g_test_result_root = NULL; static cJSON *g_load_result_root = NULL; static const char *result_json_path = NULL; extern "C" int commit_test_result_json(cJSON *node, const char *name) { + (void)name; if (g_test_result_root) { // cJSON_AddItemToObject(g_test_result_root, name, node); diff --git a/test/decoders/http/test_based_on_stellar/CMakeLists.txt b/test/decoders/http/test_based_on_stellar/CMakeLists.txt new file mode 100644 index 0000000..acc4bda --- /dev/null +++ b/test/decoders/http/test_based_on_stellar/CMakeLists.txt @@ -0,0 +1,128 @@ +set(DECODER_NAME http) + +set(TEST_RUN_DIR ${CMAKE_BINARY_DIR}/test/decoders/http) +set(SAPP_DEVEL_DIR ${TEST_RUN_DIR}/lib) +set(TEST_MAIN http_test_main) + +include_directories(${CMAKE_SOURCE_DIR}/include) +include_directories(${CMAKE_SOURCE_DIR}/test) +include_directories(/usr/local/include/cjson) +include_directories(/opt/tsg/framework/include/stellar) +include_directories(/opt/MESA/include/MESA) +include_directories(/opt/tsg/stellar/include/) + +#various ways to add -rdynamic for centos7, centos8, and different cmake version +add_definitions(-rdynamic) +link_directories(${SAPP_DEVEL_DIR}) + +# assemble test env +add_test(NAME HTTP_MKDIR_METRIC COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/metrics; mkdir -p ${TEST_RUN_DIR}/plugin; mkdir -p ${TEST_RUN_DIR}/log; mkdir -p ${TEST_RUN_DIR}/pcap") +add_test(NAME HTTP_COPY_SPEC COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/plugin/ && cp ${CMAKE_CURRENT_SOURCE_DIR}/env/spec.toml ${TEST_RUN_DIR}/plugin/spec.toml") +add_test(NAME HTTP_COPY_CONF COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/conf/ && cp ${CMAKE_CURRENT_SOURCE_DIR}/env/stellar.toml ${TEST_RUN_DIR}/conf/stellar.toml") +add_test(NAME HTTP_COPY_LOG_CONF COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/conf/ && cp ${CMAKE_CURRENT_SOURCE_DIR}/env/log.toml ${TEST_RUN_DIR}/conf/log.toml") +add_test(NAME HTTP_COPY_HTTP_DECODER_CONF COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/etc/http && cp ${CMAKE_CURRENT_SOURCE_DIR}/env/http_decoder.toml ${TEST_RUN_DIR}/etc/http/") +add_test(NAME HTTP_COPY_HTTP_GTEST_ENTRY_CONF COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/etc/http && cp ${CMAKE_CURRENT_SOURCE_DIR}/env/gtest_entry.toml ${TEST_RUN_DIR}/etc/http/") + +# update config files +add_test(NAME HTTP_UPDATE_GTEST_PLUG_ENTRY COMMAND bash -c "sed -i 's/name=.*/name=\\x22http_decoder_test_entry\\x22/' ${TEST_RUN_DIR}/etc/http/gtest_entry.toml") +add_test(NAME HTTP_UPDATE_GTEST_PLUG_TOPIC COMMAND bash -c "sed -i 's/topic=.*/topic=\\x22HTTP_DECODER_MESSAGE\\x22/' ${TEST_RUN_DIR}/etc/http/gtest_entry.toml") + +# update plugin to be tested +add_test(NAME HTTP_CP_DECODER_SO COMMAND sh -c "cp ${CMAKE_BINARY_DIR}/decoders/http/http_dyn.so ${TEST_RUN_DIR}/plugin/${DECODER_NAME}.so") +add_test(NAME HTTP_CP_DECODER_GTEST_SO COMMAND sh -c "cp ${CMAKE_BINARY_DIR}/test/decoders/http/${DECODER_NAME}_test.so ${TEST_RUN_DIR}/plugin/${DECODER_NAME}_test.so") + +set_tests_properties(HTTP_MKDIR_METRIC HTTP_COPY_SPEC HTTP_COPY_HTTP_DECODER_CONF HTTP_COPY_HTTP_GTEST_ENTRY_CONF + HTTP_COPY_CONF HTTP_COPY_LOG_CONF + HTTP_CP_DECODER_SO HTTP_CP_DECODER_GTEST_SO + HTTP_UPDATE_GTEST_PLUG_ENTRY HTTP_UPDATE_GTEST_PLUG_TOPIC + PROPERTIES FIXTURES_SETUP TestFixture) + +set(TEST_JSON_DIR ${PROJECT_SOURCE_DIR}/benchmarks/json/http) +set(TEST_PCAP_DIR ${PROJECT_SOURCE_DIR}/benchmarks/pcap/http) + +# run tests +add_test(NAME HTTP_GET_SINGLE_TRANS_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_single_trans.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_get_single_trans.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_GET_MULTI_TRANS_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_multi_trans.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_get_multi_trans.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_GET_LONG_COOKIE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_long_cookie.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_get_long_cookie.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_GET_ENCODED_URI_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_encoded_uri.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_get_encoded_uri.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_RES_GZIP_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_res_gzip.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_res_gzip.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_CHUNKED_RES_GZIP_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_chunked_res_gzip.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_chunked_res_gzip.json"WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_OVER_TCP_KEEPALIVE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_over_tcp_keepalive.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_over_tcp_keepalive.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_OVER_PPPOE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_over_pppoe.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_over_pppoe.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_OVER_TLS_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_over_tls.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_over_tls.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME NON_HTTP_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/non_http.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/non_http.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_REQ_1BYTE_SLIDING_WINDOW_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_req_1byte_sliding_window.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_req_1byte_sliding_window.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_RES_1BYTE_SLIDING_WINDOW_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_res_1byte_sliding_window.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_res_1byte_sliding_window.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_NO_CONTENT_LENGTH_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_no_content_length.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_no_content_length.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_POST_MULTIPART_FORM_DATA_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_post_multipart_form_data.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_post_multipart_form_data.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_HEADERS_EXCEED_MAXIMUM_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_hdrs_exceed_maximum.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_hdrs_exceed_maximum.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_GET_MALFORMED_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_malformed.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_get_malformed.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_URL_WITHOUT_HOST_V4_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_url_test_without_host.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_url_test_without_host.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_URL_WITHOUT_HOST_V6_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_url_test_without_host_v6.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_url_test_without_host_v6.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +#no SYN, steallar not support ! +# add_test(NAME HTTP_HEADER_VALUE_EMPTY_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_hdr_value_empty.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_hdr_value_empty.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_UPGRADE_WEBSOCKET_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_upgrade_websocket.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_upgrade_websocket.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_MULTI_PARSE_ERROR_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_multi_parse_error.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_multi_parse_error.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_GET_REQ_PIPELINE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_req_pipeline.pcap ${TEST_RUN_DIR}/pcap/test.pcap;./${TEST_MAIN} ${TEST_JSON_DIR}/http_get_req_pipeline.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_TRANS_PIPELINE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_trans_pipeline.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_trans_pipeline.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +#no SYN, steallar not support ! +# add_test(NAME HTTP_HEADER_TRUNCATED_IN_KV_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_hdr_truncated_in_kv.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_hdr_truncated_in_kv.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +# add_test(NAME HTTP_HEADER_TRUNCATED_AFTER_KV_TEST COMMAND ./${TEST_MAIN} ${TEST_JSON_DIR}/http_hdr_truncated_after_kv.json -r ${TEST_PCAP_DIR}/http_hdr_truncated_after_kv.pcap WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_FIN_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_fin.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/non_http.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +# add_test(NAME HTTP_TUNNEL_ONLY_HDR_TEST COMMAND ./${TEST_MAIN} ${TEST_JSON_DIR}/http_tunnel_s2c_only_hdr.json +# -r ${TEST_PCAP_DIR}/http_tunnel_s2c_only_hdr.pcap WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_CHN_ENCODE_URL COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_chn_encode_url.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_chn_encode_url.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_ZLIB_DEADLOCK COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_zlib_deadlock.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_zlib_deadlock.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_OUT_OF_ORDER COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_out_of_order.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_out_of_order.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_GZIP_OUT_OF_ORDER COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_gzip_out_of_order.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_gzip_out_of_order.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) + +set_tests_properties(HTTP_GET_SINGLE_TRANS_TEST + HTTP_GET_MULTI_TRANS_TEST + HTTP_GET_LONG_COOKIE_TEST + HTTP_GET_ENCODED_URI_TEST + HTTP_RES_GZIP_TEST + HTTP_CHUNKED_RES_GZIP_TEST + HTTP_OVER_TCP_KEEPALIVE_TEST + HTTP_OVER_PPPOE_TEST + HTTP_OVER_TLS_TEST + NON_HTTP_TEST + HTTP_REQ_1BYTE_SLIDING_WINDOW_TEST + HTTP_RES_1BYTE_SLIDING_WINDOW_TEST + HTTP_NO_CONTENT_LENGTH_TEST + HTTP_POST_MULTIPART_FORM_DATA_TEST + HTTP_HEADERS_EXCEED_MAXIMUM_TEST + HTTP_GET_MALFORMED_TEST + HTTP_URL_WITHOUT_HOST_V4_TEST + HTTP_URL_WITHOUT_HOST_V6_TEST + HTTP_MULTI_PARSE_ERROR_TEST + HTTP_UPGRADE_WEBSOCKET_TEST + HTTP_GET_REQ_PIPELINE_TEST + HTTP_TRANS_PIPELINE_TEST + HTTP_FIN_TEST + HTTP_CHN_ENCODE_URL + HTTP_ZLIB_DEADLOCK + HTTP_OUT_OF_ORDER + HTTP_GZIP_OUT_OF_ORDER + PROPERTIES FIXTURES_REQUIRED TestFixture) + +add_test(NAME HTTP_UPDATE_STATE_PLUG_ENTRY COMMAND bash -c "sed -i 's/name=.*/name=\\x22http_decoder_test_state_entry\\x22/' ${TEST_RUN_DIR}/etc/http/gtest_entry.toml") +add_test(NAME HTTP_UPDATE_STATE_PLUG_TOPIC COMMAND bash -c "sed -i 's/topic=.*/topic=\\x22HTTP_DECODER_MESSAGE\\x22/' ${TEST_RUN_DIR}/etc/http/gtest_entry.toml") + +set_tests_properties(HTTP_UPDATE_STATE_PLUG_ENTRY HTTP_UPDATE_STATE_PLUG_TOPIC HTTP_CP_DECODER_SO HTTP_CP_DECODER_GTEST_SO HTTP_MKDIR_METRIC + PROPERTIES FIXTURES_SETUP TestState) + +add_test(NAME HTTP_MSG_TYPE_STATE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_post.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_MSG_TYPE_STATE_C2S_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_post_c2s.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state_c2s.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_MSG_TYPE_STATE_S2C_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_post_s2c.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state_s2c.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_MSG_TYPE_STATE_PIPELINE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_multi_trans.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state_pipeline.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_MSG_TYPE_STATE_SES_EXCEPTION_C2S_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_session_exception_c2s.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state_exception_c2s.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) +add_test(NAME HTTP_MSG_TYPE_STATE_SES_EXCEPTION_S2C_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_session_exception_s2c.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state_exception_s2c.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) + +set_tests_properties(HTTP_MSG_TYPE_STATE_TEST + HTTP_MSG_TYPE_STATE_C2S_TEST + HTTP_MSG_TYPE_STATE_S2C_TEST + HTTP_MSG_TYPE_STATE_PIPELINE_TEST + HTTP_MSG_TYPE_STATE_SES_EXCEPTION_C2S_TEST + HTTP_MSG_TYPE_STATE_SES_EXCEPTION_S2C_TEST + PROPERTIES FIXTURES_REQUIRED TestState) + diff --git a/test/http_decoder/conf/gtest_entry.toml b/test/decoders/http/test_based_on_stellar/env/gtest_entry.toml similarity index 100% rename from test/http_decoder/conf/gtest_entry.toml rename to test/decoders/http/test_based_on_stellar/env/gtest_entry.toml diff --git a/test/http_decoder/conf/http_decoder.toml b/test/decoders/http/test_based_on_stellar/env/http_decoder.toml similarity index 100% rename from test/http_decoder/conf/http_decoder.toml rename to test/decoders/http/test_based_on_stellar/env/http_decoder.toml diff --git a/test/http_decoder/test_based_on_stellar/env/log.toml b/test/decoders/http/test_based_on_stellar/env/log.toml similarity index 100% rename from test/http_decoder/test_based_on_stellar/env/log.toml rename to test/decoders/http/test_based_on_stellar/env/log.toml diff --git a/test/http_decoder/test_based_on_stellar/env/spec.toml b/test/decoders/http/test_based_on_stellar/env/spec.toml similarity index 65% rename from test/http_decoder/test_based_on_stellar/env/spec.toml rename to test/decoders/http/test_based_on_stellar/env/spec.toml index 9bc3474..cce2c71 100644 --- a/test/http_decoder/test_based_on_stellar/env/spec.toml +++ b/test/decoders/http/test_based_on_stellar/env/spec.toml @@ -1,9 +1,9 @@ [[plugin]] -path = "./plugin/http_decoder.so" +path = "./plugin/http.so" init = "http_decoder_init" exit = "http_decoder_exit" [[plugin]] -path = "./plugin/http_decoder_test.so" +path = "./plugin/http_test.so" init = "http_decoder_test_init" exit = "http_decoder_test_exit" diff --git a/test/http_decoder/test_based_on_stellar/env/stellar.toml b/test/decoders/http/test_based_on_stellar/env/stellar.toml similarity index 100% rename from test/http_decoder/test_based_on_stellar/env/stellar.toml rename to test/decoders/http/test_based_on_stellar/env/stellar.toml diff --git a/test/http_decoder/CMakeLists.txt b/test/http_decoder/CMakeLists.txt deleted file mode 100644 index 98d06d3..0000000 --- a/test/http_decoder/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -set(DECODER_NAME http_decoder) - -aux_source_directory(${PROJECT_SOURCE_DIR}/deps/toml DEPS_SRC) - -add_library(${DECODER_NAME}_test SHARED http_decoder_test_plug.cpp md5.c ${DEPS_SRC}) -add_dependencies(${DECODER_NAME}_test ${DECODER_NAME}) -target_link_libraries(${DECODER_NAME}_test MESA_prof_load cjson-static) -set_target_properties(${DECODER_NAME}_test PROPERTIES PREFIX "") - -add_library(${DECODER_NAME}_perf SHARED http_decoder_perf_plug.cpp) -add_dependencies(${DECODER_NAME}_perf ${DECODER_NAME}) -set_target_properties(${DECODER_NAME}_perf PROPERTIES PREFIX "") - -set(TEST_RUN_DIR /home/mesasoft/sapp_run) - -include_directories(${CMAKE_SOURCE_DIR}/include) -include_directories(${CMAKE_SOURCE_DIR}/src) -include_directories(${CMAKE_SOURCE_DIR}/deps) -include_directories(/opt/tsg/stellar/include/) -include_directories(/opt/tsg/framework/include/) -include_directories(/opt/MESA/include/MESA) -include_directories(${CMAKE_BINARY_DIR}/vendor/vbuild/include) -include_directories(${CMAKE_BINARY_DIR}/vendor/cjson/src/cjson/include) - -aux_source_directory(${PROJECT_SOURCE_DIR}/deps/mempool PERF_TEST_DEP_SRC) -aux_source_directory(${PROJECT_SOURCE_DIR}/deps/toml PERF_TEST_DEP_SRC) -aux_source_directory(${PROJECT_SOURCE_DIR}/src PERF_TEST_DEP_SRC) - -# add_executable(httpd_perf_test ${PERF_TEST_DEP_SRC} http_decoder_perf_main.cpp http_decoder_perf_plug.cpp http_stellar_mock.cpp) -# target_link_libraries(httpd_perf_test z brotlidec llhttp-static fieldstat4 pthread) - -add_executable(httpd_gtest http_decoder_gtest.cpp http_stellar_mock.cpp ${PROJECT_SOURCE_DIR}/src/http_decoder_utils.cpp) -target_link_libraries(httpd_gtest gtest stellar_devel) diff --git a/test/http_decoder/conf/.gitkeep b/test/http_decoder/conf/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/test/http_decoder/http_stellar_mock.cpp b/test/http_decoder/http_stellar_mock.cpp deleted file mode 100644 index 4769613..0000000 --- a/test/http_decoder/http_stellar_mock.cpp +++ /dev/null @@ -1,287 +0,0 @@ -#include "uthash-2.3.0/include/utlist.h" -#include "http_decoder_gtest.h" -#include "http_stellar_mock.h" - -static int G_TCP_STREAM_TOPIC_ID = -1; -static int G_UDP_TOPIC_ID = -1; -static struct stellar *G_STELLAR; -static struct plugin_mgr *g_plugin_mgr_list_head = NULL; -static struct stellar *g_st; - -static void stellar_internal_msg_free_cb_func(void *msg, void *msg_free_arg) {/* do nothing*/} -static void stellar_register_internal_topic(struct stellar *st) -{ - G_TCP_STREAM_TOPIC_ID = stellar_mq_get_topic_id(st, TOPIC_TCP_STREAM); - if(G_TCP_STREAM_TOPIC_ID < 0){ - G_TCP_STREAM_TOPIC_ID = stellar_mq_create_topic(st, TOPIC_TCP_STREAM, stellar_internal_msg_free_cb_func, NULL); - } - G_UDP_TOPIC_ID = stellar_mq_get_topic_id(st, TOPIC_UDP); - if(G_UDP_TOPIC_ID < 0){ - G_UDP_TOPIC_ID = stellar_mq_create_topic(st, TOPIC_UDP, stellar_internal_msg_free_cb_func, NULL); - } -} -void stellar_session_plugin_dettach_current_session(struct session *sess) { return; } -int stellar_mq_destroy_topic(struct stellar *st, int topic_id) { return 0; } -int stellar_get_worker_thread_num(struct stellar *st) { return 1; } -uint16_t stellar_get_current_thread_index(void) { return 0; } -int stellar_get_current_thread_index(struct session *sess) { return 0; } -int session_mq_ignore_message(struct session *sess, int topic_id, int plugin_id) { return 0; } -int session_mq_unignore_message(struct session *sess, int topic_id, int plugin_id) { return 0; } -int stellar_session_exdata_new_index(struct stellar *st, const char *name, stellar_exdata_free *free_func,void *arg) -{ - int list_count = 0; - struct exdata_mgr *tmp, *new_exdata = (struct exdata_mgr *)calloc(1, sizeof(struct exdata_mgr)); - DL_FOREACH(st->exdata_mgr_head, tmp){ - if(0 == strcmp(tmp->name, name) && (strlen(tmp->name) == strlen(name))){ - return 0; //already exist - } - } - DL_COUNT(st->exdata_mgr_head, tmp, list_count); - new_exdata->exdata_id = list_count; - new_exdata->name = strdup(name); - new_exdata->free_func = free_func; - new_exdata->arg = arg; - DL_APPEND(st->exdata_mgr_head, new_exdata); - return 0; -} -int session_exdata_set(struct session *sess, int idx, void *ex_ptr) -{ - struct exdata_mgr *el = NULL; - DL_FOREACH(sess->runtime_exdata_head, el){ - if(el->exdata_id == idx){ - el->user_ptr = ex_ptr; - return 0; - } - } - struct exdata_mgr *new_exdata = (struct exdata_mgr *)calloc(1, sizeof(struct exdata_mgr)); - new_exdata->exdata_id = idx; - new_exdata->user_ptr = ex_ptr; - DL_APPEND(sess->runtime_exdata_head, new_exdata); - return 0; -} -void *session_exdata_get(struct session *sess, int idx) -{ - struct exdata_mgr *el = NULL; - DL_FOREACH(sess->runtime_exdata_head, el){ - if(el->exdata_id == idx){ - return el->user_ptr; - } - } - return NULL; -} -enum session_state session_get_current_state(struct session *sess) -{ - return sess->sess_state; -} -const char *session_get0_current_payload(struct session *sess, uint16_t *payload_len) -{ - const struct packet *test_payload = &sess->pkt; - *payload_len = test_payload->payload_len; - return test_payload->payload; -} -struct session_addr *session_get0_addr(struct session *sess, enum session_addr_type *addr_type) -{ - *addr_type = SESSION_ADDR_TYPE_IPV4_TCP; - return &sess->addr; -} - -const struct packet *session_get0_current_packet(struct session *sess) -{ - return &sess->pkt; -} -int session_is_symmetric(struct session *sess, unsigned char *flag) -{ - *flag = (SESSION_SEEN_C2S_FLOW | SESSION_SEEN_S2C_FLOW); - return 1; -} -static struct plugin_mgr *get_stat_by_plugin_id(int plugin_id) -{ - struct plugin_mgr *plugin = NULL; - DL_FOREACH(g_plugin_mgr_list_head, plugin){ - if(plugin->plugin_id == plugin_id){ - break; - } - } - return plugin; -} -int stellar_session_mq_subscribe(struct stellar *st, int topic_id, on_session_msg_cb_func *plugin_on_msg_cb, int plugin_id) -{ - struct topic_mgr *topic_el = NULL; - DL_FOREACH(st->topic_mgr_head, topic_el){ - if(topic_el->topic_id == topic_id){ - break; - } - } - if(NULL == topic_el){ - return -1; - } - struct plugin_mgr *plugin = get_stat_by_plugin_id(plugin_id); - struct sub_topic_cb_list *sub_cb_list = (struct sub_topic_cb_list *)calloc(1, sizeof(struct sub_topic_cb_list)); - sub_cb_list->sub_cb = plugin_on_msg_cb; - sub_cb_list->plugin_id = plugin_id; - sub_cb_list->plugin_env = plugin->plugin_env; - DL_APPEND(topic_el->sub_free_cb_list_head, sub_cb_list); - return 0; -} -int stellar_mq_get_topic_id(struct stellar *st, const char *topic_name) -{ - struct topic_mgr *el = NULL; - DL_FOREACH(st->topic_mgr_head, el){ - if(0 == strcmp(el->topic_name, topic_name) && (strlen(el->topic_name) == strlen(topic_name))){ - return el->topic_id; - } - } - return -1; -} -int stellar_session_mq_create_topic(struct stellar *st, const char *topic_name, stellar_msg_free_cb_func *msg_free_cb, void *msg_free_arg) -{ - int topic_id = stellar_mq_get_topic_id(st, topic_name); - if(topic_id >= 0){ - return topic_id;//already exist - } - struct topic_mgr *tmp, *new_topic = (struct topic_mgr *)calloc(1, sizeof(struct topic_mgr)); - int list_count; - DL_APPEND(st->topic_mgr_head, new_topic); - DL_COUNT(st->topic_mgr_head, tmp, list_count); - new_topic->topic_id = list_count; - new_topic->pub_free_cb = msg_free_cb; - new_topic->pub_free_arg = msg_free_arg; - new_topic->topic_name = strdup(topic_name); - return new_topic->topic_id; -} - -int stellar_session_plugin_register(struct stellar *st, session_ctx_new_func session_ctx_new, - session_ctx_free_func session_ctx_free, void *plugin_env) -{ - int list_count; - struct plugin_mgr *tmp, *plugin = (struct plugin_mgr *)calloc(1, sizeof(struct plugin_mgr)); - DL_APPEND(g_plugin_mgr_list_head, plugin); - DL_COUNT(g_plugin_mgr_list_head, tmp, list_count); - plugin->plugin_id = list_count; - plugin->plugin_env = plugin_env; - plugin->session_ctx_new = session_ctx_new; - plugin->session_ctx_free = session_ctx_free; - return plugin->plugin_id; -} -int session_mq_publish_message(struct session *sess, int topic_id, void *msg) -{ - struct topic_mgr *el = NULL; - DL_FOREACH(sess->st->topic_mgr_head, el){ - if(el->topic_id == topic_id){ - break; - } - } - if(NULL == el){ - return -1; - } - sub_topic_cb_list *sub_cb_node = NULL; - DL_FOREACH(el->sub_free_cb_list_head, sub_cb_node){ - (*sub_cb_node->sub_cb)(sess, topic_id, msg, NULL, sub_cb_node->plugin_env); //todo - } - el->pub_free_cb(msg, el->pub_free_arg); - return 0; -} -int stellar_load_plugin(struct stellar *st, void *(plugin_init_cb)(struct stellar *st)) -{ - plugin_init_cb(st); - return 0; -} -struct session *stellar_session_new(struct stellar *st, int topic_id, const char *payload, size_t payload_len, u_int8_t dir) -{ - struct session *sess = (struct session *)calloc(1, sizeof(struct session)); - sess->st = st; - sess->sess_state = SESSION_STATE_OPENING; - sess->addr.ipv4.saddr = 0x7f000001; - sess->addr.ipv4.daddr = 0x7f000002; - sess->addr.ipv4.sport = htons(12345); - sess->addr.ipv4.dport = htons(80); - if(G_TCP_STREAM_TOPIC_ID == topic_id){ - sess->addr_type = SESSION_ADDR_TYPE_IPV4_TCP; - }else{ - sess->addr_type = SESSION_ADDR_TYPE_IPV4_UDP; - } - sess->pkt.dir = dir; - sess->pkt.payload = payload; - sess->pkt.payload_len = payload_len; - stellar_message *message = (stellar_message *)&sess->pkt; - session_mq_publish_message(sess, topic_id, message); - return sess; -} -void stellar_session_active(struct stellar *st, struct session *sess, int topic_id, const char *payload, size_t payload_len, u_int8_t dir) -{ - sess->sess_state = SESSION_STATE_ACTIVE; - sess->pkt.dir = dir; - sess->pkt.payload = payload; - sess->pkt.payload_len = payload_len; - stellar_message *message = (stellar_message *)&sess->pkt; - session_mq_publish_message(sess, topic_id, message); - return; -} -static void session_plugin_exdata_free(struct stellar *st, struct session *sess, int exdata_idx, void *user_ptr) -{ - struct exdata_mgr *el = NULL; - DL_FOREACH(st->exdata_mgr_head, el){ - if(el->exdata_id == exdata_idx){ - el->free_func(exdata_idx, user_ptr, el->arg); - } - } -} -static void session_plugin_exdata_free_all(struct stellar *st, struct session *sess) -{ - struct exdata_mgr *el = NULL, *tmp = NULL; - DL_FOREACH_SAFE(sess->runtime_exdata_head, el, tmp){ - session_plugin_exdata_free(st, sess, el->exdata_id, el->user_ptr); - DL_DELETE(sess->runtime_exdata_head, el); - free(el); - } -} -static void stellar_session_free(struct stellar *st, struct session *sess) -{ - session_plugin_exdata_free_all(st, sess); - free(sess); -} -void stellar_session_close(struct stellar *st, struct session *sess, int topic_id) -{ - sess->sess_state = SESSION_STATE_CLOSING; - sess->pkt.payload = NULL; - sess->pkt.payload_len = 0; - stellar_message *message = (stellar_message *)&sess->pkt; - session_mq_publish_message(sess, topic_id, message); - stellar_session_free(st, sess); - return; -} -struct stellar *stellar_init(void) -{ - if(NULL == g_st){ - g_st = (struct stellar *)calloc(1, sizeof(struct stellar)); - } - stellar_register_internal_topic(g_st); - return g_st; -} -static void stellar_sub_topi_mgr_destroy(struct topic_mgr *topic_mgr) -{ - struct sub_topic_cb_list *sub_cb_node = NULL, *tmp = NULL; - DL_FOREACH_SAFE(topic_mgr->sub_free_cb_list_head, sub_cb_node, tmp){ - DL_DELETE(topic_mgr->sub_free_cb_list_head, sub_cb_node); - free(sub_cb_node); - } - return; -} -void stellar_destroy(struct stellar *st) -{ - struct exdata_mgr *el = NULL, *tmp; - DL_FOREACH_SAFE(st->exdata_mgr_head, el, tmp){ - free((void *)el->name); - DL_DELETE(st->exdata_mgr_head, el); - free(el); - } - struct topic_mgr *el_topic, *tmp_topic; - DL_FOREACH_SAFE(st->topic_mgr_head, el_topic, tmp_topic){ - DL_DELETE(st->topic_mgr_head, el_topic); - stellar_sub_topi_mgr_destroy(el_topic); - free((void *)el_topic->topic_name); - free(el_topic); - } - free(st); - return; -} \ No newline at end of file diff --git a/test/http_decoder/http_stellar_mock.h b/test/http_decoder/http_stellar_mock.h deleted file mode 100644 index 8192a98..0000000 --- a/test/http_decoder/http_stellar_mock.h +++ /dev/null @@ -1,112 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#ifdef __cplusplus -extern "C" -{ -#endif -#include -#include -#include -#include -#ifdef __cplusplus -} -#endif - -struct packet{ - const char *payload; - size_t payload_len; - u_int8_t dir; //FLOW_DIRECTION_C2S FLOW_DIRECTION_S2C -}; -typedef struct packet stellar_message; -struct exdata_mgr{ - const char *name; - int exdata_id; - void *arg; - void *user_ptr; - stellar_exdata_free *free_func; - struct exdata_mgr *next, *prev; -}; -struct sub_topic_mgr{ - int topic_id; - int plugin_id; - void *plugin_env; -}; -struct topic_mgr{ - struct topic_mgr *next, *prev; - const char *topic_name; - int topic_id; - stellar_msg_free_cb_func *pub_free_cb; - void *pub_free_arg; - struct sub_topic_cb_list *sub_free_cb_list_head; -}; -struct stellar{ - struct topic_mgr *topic_mgr_head; - struct exdata_mgr *exdata_mgr_head; -}; - -//todo, native stellar can't get addr -enum session_addr_type -{ - SESSION_ADDR_TYPE_IPV4_TCP, - SESSION_ADDR_TYPE_IPV4_UDP, - SESSION_ADDR_TYPE_IPV6_TCP, - SESSION_ADDR_TYPE_IPV6_UDP, - SESSION_ADDR_TYPE_UNKNOWN, - __SESSION_ADDR_TYPE_MAX, -}; -struct session_addr_ipv4{ - uint32_t saddr; /* network order */ - uint32_t daddr; /* network order */ - uint16_t sport; /* network order */ - uint16_t dport; /* network order */ -}; - -#include -#ifndef IPV6_ADDR_LEN -#define IPV6_ADDR_LEN (sizeof(struct in6_addr)) -#endif -struct session_addr_ipv6 -{ - uint8_t saddr[IPV6_ADDR_LEN] ; - uint8_t daddr[IPV6_ADDR_LEN] ; - uint16_t sport; /* network order */ - uint16_t dport; /* network order */ -}; - -struct session_addr -{ - union - { - struct session_addr_ipv4 ipv4; - struct session_addr_ipv6 ipv6; - }; -}; - - -struct session{ - struct stellar *st; - enum session_state sess_state; - enum session_addr_type addr_type; - struct session_addr addr; - void *exdata; - struct packet pkt; - struct exdata_mgr *runtime_exdata_head; -}; -struct plugin_mgr{ - struct plugin_mgr *next, *prev; - int plugin_id; - void *plugin_env; - session_ctx_new_func *session_ctx_new; - session_ctx_free_func *session_ctx_free; -}; -struct sub_topic_cb_list{ - int plugin_id; - void *plugin_env; - on_session_msg_cb_func *sub_cb; - struct sub_topic_cb_list *next, *prev; -}; diff --git a/test/http_decoder/test_based_on_stellar/CMakeLists.txt b/test/http_decoder/test_based_on_stellar/CMakeLists.txt deleted file mode 100644 index be76c16..0000000 --- a/test/http_decoder/test_based_on_stellar/CMakeLists.txt +++ /dev/null @@ -1,142 +0,0 @@ -set(DECODER_NAME http_decoder) - -set(TEST_RUN_DIR ${CMAKE_INSTALL_PREFIX}/stellar) -set(SAPP_DEVEL_DIR ${TEST_RUN_DIR}/lib) -set(TEST_MAIN plugin_test_main) - -include_directories(${CMAKE_SOURCE_DIR}/include) -include_directories(${CMAKE_SOURCE_DIR}/test) -include_directories(/usr/local/include/cjson) -include_directories(/opt/tsg/framework/include/stellar) -include_directories(/opt/MESA/include/MESA) -include_directories(/opt/tsg/stellar/include/) - -#various ways to add -rdynamic for centos7, centos8, and different cmake version -add_definitions(-rdynamic) -link_directories(${SAPP_DEVEL_DIR}) - -add_executable(plugin_test_main plugin_test_main.cpp) -set_target_properties(plugin_test_main - PROPERTIES - LINK_OPTIONS - "-rdynamic" - ) -set_target_properties(plugin_test_main - PROPERTIES - LINK_FLAGS - "-rdynamic" - ) -set(LINK_FLAGS "-rdynamic") -target_link_libraries(plugin_test_main gtest cjson-static stellar_devel) - -# assemble test env -add_test(NAME STELLAR_MKDIR_METRIC COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/metrics; mkdir -p ${TEST_RUN_DIR}/plugin; mkdir -p ${TEST_RUN_DIR}/log; mkdir -p ${TEST_RUN_DIR}/pcap") -add_test(NAME STELLAR_INSTALL_TEST_MAIN COMMAND sh -c "cp ${CMAKE_CURRENT_BINARY_DIR}/${TEST_MAIN} ${TEST_RUN_DIR}/${TEST_MAIN}") -add_test(NAME STELLAR_COPY_SPEC COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/plugin/ && cp ${CMAKE_CURRENT_SOURCE_DIR}/env/spec.toml ${TEST_RUN_DIR}/plugin/spec.toml") -add_test(NAME STELLAR_COPY_STELLAR_CONF COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/conf/ && cp ${CMAKE_CURRENT_SOURCE_DIR}/env/stellar.toml ${TEST_RUN_DIR}/conf/stellar.toml") -add_test(NAME STELLAR_COPY_STELLAR_LOG_CONF COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/conf/ && cp ${CMAKE_CURRENT_SOURCE_DIR}/env/log.toml ${TEST_RUN_DIR}/conf/log.toml") -add_test(NAME STELLAR_COPY_HTTP_DECODER_CONF COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/etc/http && cp ${PROJECT_SOURCE_DIR}/conf/http_decoder.toml ${TEST_RUN_DIR}/etc/http/") -add_test(NAME STELLAR_COPY_HTTP_GTEST_ENTRY_CONF COMMAND sh -c "mkdir -p ${TEST_RUN_DIR}/etc/http && cp ${PROJECT_SOURCE_DIR}/conf/gtest_entry.toml ${TEST_RUN_DIR}/etc/http/") - -# update config files -add_test(NAME UPDATE_GTEST_PLUG_ENTRY COMMAND bash -c "sed -i 's/name=.*/name=\\x22http_decoder_test_entry\\x22/' ${TEST_RUN_DIR}/etc/http/gtest_entry.toml") -add_test(NAME UPDATE_GTEST_PLUG_TOPIC COMMAND bash -c "sed -i 's/topic=.*/topic=\\x22HTTP_DECODER_MESSAGE\\x22/' ${TEST_RUN_DIR}/etc/http/gtest_entry.toml") - -# update plugin to be tested -add_test(NAME STELLAR_HTTP_DECODER_SO COMMAND sh -c "cp ${CMAKE_BINARY_DIR}/src/${DECODER_NAME}.so ${TEST_RUN_DIR}/plugin/${DECODER_NAME}.so") -add_test(NAME STELLAR_HTTP_DECODER_GTEST_SO COMMAND sh -c "cp ${CMAKE_BINARY_DIR}/test/${DECODER_NAME}_test.so ${TEST_RUN_DIR}/plugin/${DECODER_NAME}_test.so") - -set_tests_properties(STELLAR_MKDIR_METRIC STELLAR_INSTALL_TEST_MAIN STELLAR_COPY_SPEC STELLAR_COPY_HTTP_DECODER_CONF STELLAR_COPY_HTTP_GTEST_ENTRY_CONF - STELLAR_COPY_STELLAR_CONF STELLAR_COPY_STELLAR_LOG_CONF - STELLAR_HTTP_DECODER_SO STELLAR_HTTP_DECODER_GTEST_SO - UPDATE_GTEST_PLUG_ENTRY UPDATE_GTEST_PLUG_TOPIC - PROPERTIES FIXTURES_SETUP TestFixture) - -set(TEST_JSON_DIR ${PROJECT_SOURCE_DIR}/test/test_result_json) -set(TEST_PCAP_DIR ${PROJECT_SOURCE_DIR}/test/http_pcap) - -# run tests -add_test(NAME STELLAR_HTTP_GET_SINGLE_TRANS_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_single_trans.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_get_single_trans.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_GET_MULTI_TRANS_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_multi_trans.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_get_multi_trans.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_GET_LONG_COOKIE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_long_cookie.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_get_long_cookie.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_GET_ENCODED_URI_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_encoded_uri.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_get_encoded_uri.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_RES_GZIP_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_res_gzip.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_res_gzip.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_CHUNKED_RES_GZIP_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_chunked_res_gzip.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_chunked_res_gzip.json"WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_OVER_TCP_KEEPALIVE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_over_tcp_keepalive.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_over_tcp_keepalive.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_OVER_PPPOE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_over_pppoe.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_over_pppoe.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_OVER_TLS_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_over_tls.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_over_tls.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_NON_HTTP_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/non_http.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/non_http.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_REQ_1BYTE_SLIDING_WINDOW_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_req_1byte_sliding_window.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_req_1byte_sliding_window.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_RES_1BYTE_SLIDING_WINDOW_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_res_1byte_sliding_window.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_res_1byte_sliding_window.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_NO_CONTENT_LENGTH_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_no_content_length.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_no_content_length.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_POST_MULTIPART_FORM_DATA_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_post_multipart_form_data.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_post_multipart_form_data.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_HEADERS_EXCEED_MAXIMUM_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_hdrs_exceed_maximum.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_hdrs_exceed_maximum.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_GET_MALFORMED_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_malformed.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_get_malformed.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_URL_WITHOUT_HOST_V4_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_url_test_without_host.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_url_test_without_host.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_URL_WITHOUT_HOST_V6_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_url_test_without_host_v6.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_url_test_without_host_v6.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -#no SYN, steallar not support ! -# add_test(NAME STELLAR_HTTP_HEADER_VALUE_EMPTY_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_hdr_value_empty.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_hdr_value_empty.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_UPGRADE_WEBSOCKET_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_upgrade_websocket.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_upgrade_websocket.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_MULTI_PARSE_ERROR_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_multi_parse_error.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_multi_parse_error.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_GET_REQ_PIPELINE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_req_pipeline.pcap ${TEST_RUN_DIR}/pcap/test.pcap;./${TEST_MAIN} ${TEST_JSON_DIR}/http_get_req_pipeline.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_TRANS_PIPELINE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_trans_pipeline.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_trans_pipeline.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -#no SYN, steallar not support ! -# add_test(NAME STELLAR_HTTP_HEADER_TRUNCATED_IN_KV_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_hdr_truncated_in_kv.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_hdr_truncated_in_kv.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -# add_test(NAME STELLAR_HTTP_HEADER_TRUNCATED_AFTER_KV_TEST COMMAND ./${TEST_MAIN} ${TEST_JSON_DIR}/http_hdr_truncated_after_kv.json -r ${TEST_PCAP_DIR}/http_hdr_truncated_after_kv.pcap WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_FIN_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_fin.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/non_http.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -# add_test(NAME STELLAR_HTTP_TUNNEL_ONLY_HDR_TEST COMMAND ./${TEST_MAIN} ${TEST_JSON_DIR}/http_tunnel_s2c_only_hdr.json -# -r ${TEST_PCAP_DIR}/http_tunnel_s2c_only_hdr.pcap WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_CHN_ENCODE_URL COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_chn_encode_url.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_chn_encode_url.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_ZLIB_DEADLOCK COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_zlib_deadlock.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_zlib_deadlock.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_OUT_OF_ORDER COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_out_of_order.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_out_of_order.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_GZIP_OUT_OF_ORDER COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_gzip_out_of_order.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_gzip_out_of_order.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) - -set_tests_properties(STELLAR_HTTP_GET_SINGLE_TRANS_TEST - STELLAR_HTTP_GET_MULTI_TRANS_TEST - STELLAR_HTTP_GET_LONG_COOKIE_TEST - STELLAR_HTTP_GET_ENCODED_URI_TEST - STELLAR_HTTP_RES_GZIP_TEST - STELLAR_HTTP_CHUNKED_RES_GZIP_TEST - STELLAR_HTTP_OVER_TCP_KEEPALIVE_TEST - STELLAR_HTTP_OVER_PPPOE_TEST - STELLAR_HTTP_OVER_TLS_TEST - STELLAR_NON_HTTP_TEST - STELLAR_HTTP_REQ_1BYTE_SLIDING_WINDOW_TEST - STELLAR_HTTP_RES_1BYTE_SLIDING_WINDOW_TEST - STELLAR_HTTP_NO_CONTENT_LENGTH_TEST - STELLAR_HTTP_POST_MULTIPART_FORM_DATA_TEST - STELLAR_HTTP_HEADERS_EXCEED_MAXIMUM_TEST - STELLAR_HTTP_GET_MALFORMED_TEST - STELLAR_HTTP_URL_WITHOUT_HOST_V4_TEST - STELLAR_HTTP_URL_WITHOUT_HOST_V6_TEST - STELLAR_HTTP_MULTI_PARSE_ERROR_TEST - STELLAR_HTTP_UPGRADE_WEBSOCKET_TEST - STELLAR_HTTP_GET_REQ_PIPELINE_TEST - STELLAR_HTTP_TRANS_PIPELINE_TEST - STELLAR_HTTP_FIN_TEST - STELLAR_HTTP_CHN_ENCODE_URL - STELLAR_HTTP_ZLIB_DEADLOCK - STELLAR_HTTP_OUT_OF_ORDER - STELLAR_HTTP_GZIP_OUT_OF_ORDER - PROPERTIES FIXTURES_REQUIRED TestFixture) - -add_test(NAME UPDATE_STATE_PLUG_ENTRY COMMAND bash -c "sed -i 's/name=.*/name=\\x22http_decoder_test_state_entry\\x22/' ${TEST_RUN_DIR}/etc/http/gtest_entry.toml") -add_test(NAME UPDATE_STATE_PLUG_TOPIC COMMAND bash -c "sed -i 's/topic=.*/topic=\\x22HTTP_DECODER_MESSAGE\\x22/' ${TEST_RUN_DIR}/etc/http/gtest_entry.toml") - -set_tests_properties(UPDATE_STATE_PLUG_ENTRY UPDATE_STATE_PLUG_TOPIC STELLAR_HTTP_DECODER_SO STELLAR_HTTP_DECODER_GTEST_SO STELLAR_MKDIR_METRIC - PROPERTIES FIXTURES_SETUP TestState) - -add_test(NAME STELLAR_HTTP_MSG_TYPE_STATE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_post.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_MSG_TYPE_STATE_C2S_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_post_c2s.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state_c2s.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_MSG_TYPE_STATE_S2C_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_post_s2c.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state_s2c.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_MSG_TYPE_STATE_PIPELINE_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_get_multi_trans.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state_pipeline.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_MSG_TYPE_STATE_SES_EXCEPTION_C2S_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_session_exception_c2s.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state_exception_c2s.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) -add_test(NAME STELLAR_HTTP_MSG_TYPE_STATE_SES_EXCEPTION_S2C_TEST COMMAND sh -c "ln -sf ${TEST_PCAP_DIR}/http_session_exception_s2c.pcap ${TEST_RUN_DIR}/pcap/test.pcap; ./${TEST_MAIN} ${TEST_JSON_DIR}/http_msg_type_state_exception_s2c.json" WORKING_DIRECTORY ${TEST_RUN_DIR}) - -set_tests_properties(STELLAR_HTTP_MSG_TYPE_STATE_TEST - STELLAR_HTTP_MSG_TYPE_STATE_C2S_TEST - STELLAR_HTTP_MSG_TYPE_STATE_S2C_TEST - STELLAR_HTTP_MSG_TYPE_STATE_PIPELINE_TEST - STELLAR_HTTP_MSG_TYPE_STATE_SES_EXCEPTION_C2S_TEST - STELLAR_HTTP_MSG_TYPE_STATE_SES_EXCEPTION_S2C_TEST - PROPERTIES FIXTURES_REQUIRED TestState) diff --git a/test/http_decoder/uthash-2.3.0/include/utarray.h b/test/http_decoder/uthash-2.3.0/include/utarray.h deleted file mode 100644 index 992fe7c..0000000 --- a/test/http_decoder/uthash-2.3.0/include/utarray.h +++ /dev/null @@ -1,248 +0,0 @@ -/* -Copyright (c) 2008-2021, Troy D. Hanson http://troydhanson.github.com/uthash/ -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* a dynamic array implementation using macros - */ -#ifndef UTARRAY_H -#define UTARRAY_H - -#define UTARRAY_VERSION 2.3.0 - -#include /* size_t */ -#include /* memset, etc */ -#include /* exit */ - -#ifdef __GNUC__ -#define UTARRAY_UNUSED __attribute__((__unused__)) -#else -#define UTARRAY_UNUSED -#endif - -#ifdef oom -#error "The name of macro 'oom' has been changed to 'utarray_oom'. Please update your code." -#define utarray_oom() oom() -#endif - -#ifndef utarray_oom -#define utarray_oom() exit(-1) -#endif - -typedef void (ctor_f)(void *dst, const void *src); -typedef void (dtor_f)(void *elt); -typedef void (init_f)(void *elt); -typedef struct { - size_t sz; - init_f *init; - ctor_f *copy; - dtor_f *dtor; -} UT_icd; - -typedef struct { - unsigned i,n;/* i: index of next available slot, n: num slots */ - UT_icd icd; /* initializer, copy and destructor functions */ - char *d; /* n slots of size icd->sz*/ -} UT_array; - -#define utarray_init(a,_icd) do { \ - memset(a,0,sizeof(UT_array)); \ - (a)->icd = *(_icd); \ -} while(0) - -#define utarray_done(a) do { \ - if ((a)->n) { \ - if ((a)->icd.dtor) { \ - unsigned _ut_i; \ - for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \ - (a)->icd.dtor(utarray_eltptr(a,_ut_i)); \ - } \ - } \ - free((a)->d); \ - } \ - (a)->n=0; \ -} while(0) - -#define utarray_new(a,_icd) do { \ - (a) = (UT_array*)malloc(sizeof(UT_array)); \ - if ((a) == NULL) { \ - utarray_oom(); \ - } \ - utarray_init(a,_icd); \ -} while(0) - -#define utarray_free(a) do { \ - utarray_done(a); \ - free(a); \ -} while(0) - -#define utarray_reserve(a,by) do { \ - if (((a)->i+(by)) > (a)->n) { \ - char *utarray_tmp; \ - while (((a)->i+(by)) > (a)->n) { (a)->n = ((a)->n ? (2*(a)->n) : 8); } \ - utarray_tmp=(char*)realloc((a)->d, (a)->n*(a)->icd.sz); \ - if (utarray_tmp == NULL) { \ - utarray_oom(); \ - } \ - (a)->d=utarray_tmp; \ - } \ -} while(0) - -#define utarray_push_back(a,p) do { \ - utarray_reserve(a,1); \ - if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,(a)->i++), p); } \ - else { memcpy(_utarray_eltptr(a,(a)->i++), p, (a)->icd.sz); }; \ -} while(0) - -#define utarray_pop_back(a) do { \ - if ((a)->icd.dtor) { (a)->icd.dtor( _utarray_eltptr(a,--((a)->i))); } \ - else { (a)->i--; } \ -} while(0) - -#define utarray_extend_back(a) do { \ - utarray_reserve(a,1); \ - if ((a)->icd.init) { (a)->icd.init(_utarray_eltptr(a,(a)->i)); } \ - else { memset(_utarray_eltptr(a,(a)->i),0,(a)->icd.sz); } \ - (a)->i++; \ -} while(0) - -#define utarray_len(a) ((a)->i) - -#define utarray_eltptr(a,j) (((j) < (a)->i) ? _utarray_eltptr(a,j) : NULL) -#define _utarray_eltptr(a,j) ((void*)((a)->d + ((a)->icd.sz * (j)))) - -#define utarray_insert(a,p,j) do { \ - if ((j) > (a)->i) utarray_resize(a,j); \ - utarray_reserve(a,1); \ - if ((j) < (a)->i) { \ - memmove( _utarray_eltptr(a,(j)+1), _utarray_eltptr(a,j), \ - ((a)->i - (j))*((a)->icd.sz)); \ - } \ - if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,j), p); } \ - else { memcpy(_utarray_eltptr(a,j), p, (a)->icd.sz); }; \ - (a)->i++; \ -} while(0) - -#define utarray_inserta(a,w,j) do { \ - if (utarray_len(w) == 0) break; \ - if ((j) > (a)->i) utarray_resize(a,j); \ - utarray_reserve(a,utarray_len(w)); \ - if ((j) < (a)->i) { \ - memmove(_utarray_eltptr(a,(j)+utarray_len(w)), \ - _utarray_eltptr(a,j), \ - ((a)->i - (j))*((a)->icd.sz)); \ - } \ - if ((a)->icd.copy) { \ - unsigned _ut_i; \ - for(_ut_i=0;_ut_i<(w)->i;_ut_i++) { \ - (a)->icd.copy(_utarray_eltptr(a, (j) + _ut_i), _utarray_eltptr(w, _ut_i)); \ - } \ - } else { \ - memcpy(_utarray_eltptr(a,j), _utarray_eltptr(w,0), \ - utarray_len(w)*((a)->icd.sz)); \ - } \ - (a)->i += utarray_len(w); \ -} while(0) - -#define utarray_resize(dst,num) do { \ - unsigned _ut_i; \ - if ((dst)->i > (unsigned)(num)) { \ - if ((dst)->icd.dtor) { \ - for (_ut_i = (num); _ut_i < (dst)->i; ++_ut_i) { \ - (dst)->icd.dtor(_utarray_eltptr(dst, _ut_i)); \ - } \ - } \ - } else if ((dst)->i < (unsigned)(num)) { \ - utarray_reserve(dst, (num) - (dst)->i); \ - if ((dst)->icd.init) { \ - for (_ut_i = (dst)->i; _ut_i < (unsigned)(num); ++_ut_i) { \ - (dst)->icd.init(_utarray_eltptr(dst, _ut_i)); \ - } \ - } else { \ - memset(_utarray_eltptr(dst, (dst)->i), 0, (dst)->icd.sz*((num) - (dst)->i)); \ - } \ - } \ - (dst)->i = (num); \ -} while(0) - -#define utarray_concat(dst,src) do { \ - utarray_inserta(dst, src, utarray_len(dst)); \ -} while(0) - -#define utarray_erase(a,pos,len) do { \ - if ((a)->icd.dtor) { \ - unsigned _ut_i; \ - for (_ut_i = 0; _ut_i < (len); _ut_i++) { \ - (a)->icd.dtor(utarray_eltptr(a, (pos) + _ut_i)); \ - } \ - } \ - if ((a)->i > ((pos) + (len))) { \ - memmove(_utarray_eltptr(a, pos), _utarray_eltptr(a, (pos) + (len)), \ - ((a)->i - ((pos) + (len))) * (a)->icd.sz); \ - } \ - (a)->i -= (len); \ -} while(0) - -#define utarray_renew(a,u) do { \ - if (a) utarray_clear(a); \ - else utarray_new(a, u); \ -} while(0) - -#define utarray_clear(a) do { \ - if ((a)->i > 0) { \ - if ((a)->icd.dtor) { \ - unsigned _ut_i; \ - for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \ - (a)->icd.dtor(_utarray_eltptr(a, _ut_i)); \ - } \ - } \ - (a)->i = 0; \ - } \ -} while(0) - -#define utarray_sort(a,cmp) do { \ - qsort((a)->d, (a)->i, (a)->icd.sz, cmp); \ -} while(0) - -#define utarray_find(a,v,cmp) bsearch((v),(a)->d,(a)->i,(a)->icd.sz,cmp) - -#define utarray_front(a) (((a)->i) ? (_utarray_eltptr(a,0)) : NULL) -#define utarray_next(a,e) (((e)==NULL) ? utarray_front(a) : (((a)->i != utarray_eltidx(a,e)+1) ? _utarray_eltptr(a,utarray_eltidx(a,e)+1) : NULL)) -#define utarray_prev(a,e) (((e)==NULL) ? utarray_back(a) : ((utarray_eltidx(a,e) != 0) ? _utarray_eltptr(a,utarray_eltidx(a,e)-1) : NULL)) -#define utarray_back(a) (((a)->i) ? (_utarray_eltptr(a,(a)->i-1)) : NULL) -#define utarray_eltidx(a,e) (((char*)(e) - (a)->d) / (a)->icd.sz) - -/* last we pre-define a few icd for common utarrays of ints and strings */ -static void utarray_str_cpy(void *dst, const void *src) { - char *const *srcc = (char *const *)src; - char **dstc = (char**)dst; - *dstc = (*srcc == NULL) ? NULL : strdup(*srcc); -} -static void utarray_str_dtor(void *elt) { - char **eltc = (char**)elt; - if (*eltc != NULL) free(*eltc); -} -static const UT_icd ut_str_icd UTARRAY_UNUSED = {sizeof(char*),NULL,utarray_str_cpy,utarray_str_dtor}; -static const UT_icd ut_int_icd UTARRAY_UNUSED = {sizeof(int),NULL,NULL,NULL}; -static const UT_icd ut_ptr_icd UTARRAY_UNUSED = {sizeof(void*),NULL,NULL,NULL}; - - -#endif /* UTARRAY_H */ diff --git a/test/http_decoder/uthash-2.3.0/include/uthash.h b/test/http_decoder/uthash-2.3.0/include/uthash.h deleted file mode 100644 index ac78fda..0000000 --- a/test/http_decoder/uthash-2.3.0/include/uthash.h +++ /dev/null @@ -1,1136 +0,0 @@ -/* -Copyright (c) 2003-2021, Troy D. Hanson http://troydhanson.github.com/uthash/ -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef UTHASH_H -#define UTHASH_H - -#define UTHASH_VERSION 2.3.0 - -#include /* memcmp, memset, strlen */ -#include /* ptrdiff_t */ -#include /* exit */ - -#if defined(HASH_DEFINE_OWN_STDINT) && HASH_DEFINE_OWN_STDINT -/* This codepath is provided for backward compatibility, but I plan to remove it. */ -#warning "HASH_DEFINE_OWN_STDINT is deprecated; please use HASH_NO_STDINT instead" -typedef unsigned int uint32_t; -typedef unsigned char uint8_t; -#elif defined(HASH_NO_STDINT) && HASH_NO_STDINT -#else -#include /* uint8_t, uint32_t */ -#endif - -/* These macros use decltype or the earlier __typeof GNU extension. - As decltype is only available in newer compilers (VS2010 or gcc 4.3+ - when compiling c++ source) this code uses whatever method is needed - or, for VS2008 where neither is available, uses casting workarounds. */ -#if !defined(DECLTYPE) && !defined(NO_DECLTYPE) -#if defined(_MSC_VER) /* MS compiler */ -#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ -#define DECLTYPE(x) (decltype(x)) -#else /* VS2008 or older (or VS2010 in C mode) */ -#define NO_DECLTYPE -#endif -#elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) -#define NO_DECLTYPE -#else /* GNU, Sun and other compilers */ -#define DECLTYPE(x) (__typeof(x)) -#endif -#endif - -#ifdef NO_DECLTYPE -#define DECLTYPE(x) -#define DECLTYPE_ASSIGN(dst,src) \ -do { \ - char **_da_dst = (char**)(&(dst)); \ - *_da_dst = (char*)(src); \ -} while (0) -#else -#define DECLTYPE_ASSIGN(dst,src) \ -do { \ - (dst) = DECLTYPE(dst)(src); \ -} while (0) -#endif - -#ifndef uthash_malloc -#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ -#endif -#ifndef uthash_free -#define uthash_free(ptr,sz) free(ptr) /* free fcn */ -#endif -#ifndef uthash_bzero -#define uthash_bzero(a,n) memset(a,'\0',n) -#endif -#ifndef uthash_strlen -#define uthash_strlen(s) strlen(s) -#endif - -#ifndef HASH_FUNCTION -#define HASH_FUNCTION(keyptr,keylen,hashv) HASH_JEN(keyptr, keylen, hashv) -#endif - -#ifndef HASH_KEYCMP -#define HASH_KEYCMP(a,b,n) memcmp(a,b,n) -#endif - -#ifndef uthash_noexpand_fyi -#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ -#endif -#ifndef uthash_expand_fyi -#define uthash_expand_fyi(tbl) /* can be defined to log expands */ -#endif - -#ifndef HASH_NONFATAL_OOM -#define HASH_NONFATAL_OOM 0 -#endif - -#if HASH_NONFATAL_OOM -/* malloc failures can be recovered from */ - -#ifndef uthash_nonfatal_oom -#define uthash_nonfatal_oom(obj) do {} while (0) /* non-fatal OOM error */ -#endif - -#define HASH_RECORD_OOM(oomed) do { (oomed) = 1; } while (0) -#define IF_HASH_NONFATAL_OOM(x) x - -#else -/* malloc failures result in lost memory, hash tables are unusable */ - -#ifndef uthash_fatal -#define uthash_fatal(msg) exit(-1) /* fatal OOM error */ -#endif - -#define HASH_RECORD_OOM(oomed) uthash_fatal("out of memory") -#define IF_HASH_NONFATAL_OOM(x) - -#endif - -/* initial number of buckets */ -#define HASH_INITIAL_NUM_BUCKETS 32U /* initial number of buckets */ -#define HASH_INITIAL_NUM_BUCKETS_LOG2 5U /* lg2 of initial number of buckets */ -#define HASH_BKT_CAPACITY_THRESH 10U /* expand when bucket count reaches */ - -/* calculate the element whose hash handle address is hhp */ -#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) -/* calculate the hash handle from element address elp */ -#define HH_FROM_ELMT(tbl,elp) ((UT_hash_handle*)(void*)(((char*)(elp)) + ((tbl)->hho))) - -#define HASH_ROLLBACK_BKT(hh, head, itemptrhh) \ -do { \ - struct UT_hash_handle *_hd_hh_item = (itemptrhh); \ - unsigned _hd_bkt; \ - HASH_TO_BKT(_hd_hh_item->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ - (head)->hh.tbl->buckets[_hd_bkt].count++; \ - _hd_hh_item->hh_next = NULL; \ - _hd_hh_item->hh_prev = NULL; \ -} while (0) - -#define HASH_VALUE(keyptr,keylen,hashv) \ -do { \ - HASH_FUNCTION(keyptr, keylen, hashv); \ -} while (0) - -#define HASH_FIND_BYHASHVALUE(hh,head,keyptr,keylen,hashval,out) \ -do { \ - (out) = NULL; \ - if (head) { \ - unsigned _hf_bkt; \ - HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _hf_bkt); \ - if (HASH_BLOOM_TEST((head)->hh.tbl, hashval) != 0) { \ - HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], keyptr, keylen, hashval, out); \ - } \ - } \ -} while (0) - -#define HASH_FIND(hh,head,keyptr,keylen,out) \ -do { \ - (out) = NULL; \ - if (head) { \ - unsigned _hf_hashv; \ - HASH_VALUE(keyptr, keylen, _hf_hashv); \ - HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out); \ - } \ -} while (0) - -#ifdef HASH_BLOOM -#define HASH_BLOOM_BITLEN (1UL << HASH_BLOOM) -#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8UL) + (((HASH_BLOOM_BITLEN%8UL)!=0UL) ? 1UL : 0UL) -#define HASH_BLOOM_MAKE(tbl,oomed) \ -do { \ - (tbl)->bloom_nbits = HASH_BLOOM; \ - (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ - if (!(tbl)->bloom_bv) { \ - HASH_RECORD_OOM(oomed); \ - } else { \ - uthash_bzero((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ - (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ - } \ -} while (0) - -#define HASH_BLOOM_FREE(tbl) \ -do { \ - uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ -} while (0) - -#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8U] |= (1U << ((idx)%8U))) -#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8U] & (1U << ((idx)%8U))) - -#define HASH_BLOOM_ADD(tbl,hashv) \ - HASH_BLOOM_BITSET((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) - -#define HASH_BLOOM_TEST(tbl,hashv) \ - HASH_BLOOM_BITTEST((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) - -#else -#define HASH_BLOOM_MAKE(tbl,oomed) -#define HASH_BLOOM_FREE(tbl) -#define HASH_BLOOM_ADD(tbl,hashv) -#define HASH_BLOOM_TEST(tbl,hashv) (1) -#define HASH_BLOOM_BYTELEN 0U -#endif - -#define HASH_MAKE_TABLE(hh,head,oomed) \ -do { \ - (head)->hh.tbl = (UT_hash_table*)uthash_malloc(sizeof(UT_hash_table)); \ - if (!(head)->hh.tbl) { \ - HASH_RECORD_OOM(oomed); \ - } else { \ - uthash_bzero((head)->hh.tbl, sizeof(UT_hash_table)); \ - (head)->hh.tbl->tail = &((head)->hh); \ - (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ - (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ - (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ - (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ - HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ - (head)->hh.tbl->signature = HASH_SIGNATURE; \ - if (!(head)->hh.tbl->buckets) { \ - HASH_RECORD_OOM(oomed); \ - uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ - } else { \ - uthash_bzero((head)->hh.tbl->buckets, \ - HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ - HASH_BLOOM_MAKE((head)->hh.tbl, oomed); \ - IF_HASH_NONFATAL_OOM( \ - if (oomed) { \ - uthash_free((head)->hh.tbl->buckets, \ - HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ - uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ - } \ - ) \ - } \ - } \ -} while (0) - -#define HASH_REPLACE_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,replaced,cmpfcn) \ -do { \ - (replaced) = NULL; \ - HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ - if (replaced) { \ - HASH_DELETE(hh, head, replaced); \ - } \ - HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn); \ -} while (0) - -#define HASH_REPLACE_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add,replaced) \ -do { \ - (replaced) = NULL; \ - HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ - if (replaced) { \ - HASH_DELETE(hh, head, replaced); \ - } \ - HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add); \ -} while (0) - -#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \ -do { \ - unsigned _hr_hashv; \ - HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ - HASH_REPLACE_BYHASHVALUE(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced); \ -} while (0) - -#define HASH_REPLACE_INORDER(hh,head,fieldname,keylen_in,add,replaced,cmpfcn) \ -do { \ - unsigned _hr_hashv; \ - HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ - HASH_REPLACE_BYHASHVALUE_INORDER(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced, cmpfcn); \ -} while (0) - -#define HASH_APPEND_LIST(hh, head, add) \ -do { \ - (add)->hh.next = NULL; \ - (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ - (head)->hh.tbl->tail->next = (add); \ - (head)->hh.tbl->tail = &((add)->hh); \ -} while (0) - -#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ -do { \ - do { \ - if (cmpfcn(DECLTYPE(head)(_hs_iter), add) > 0) { \ - break; \ - } \ - } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ -} while (0) - -#ifdef NO_DECLTYPE -#undef HASH_AKBI_INNER_LOOP -#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ -do { \ - char *_hs_saved_head = (char*)(head); \ - do { \ - DECLTYPE_ASSIGN(head, _hs_iter); \ - if (cmpfcn(head, add) > 0) { \ - DECLTYPE_ASSIGN(head, _hs_saved_head); \ - break; \ - } \ - DECLTYPE_ASSIGN(head, _hs_saved_head); \ - } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ -} while (0) -#endif - -#if HASH_NONFATAL_OOM - -#define HASH_ADD_TO_TABLE(hh,head,keyptr,keylen_in,hashval,add,oomed) \ -do { \ - if (!(oomed)) { \ - unsigned _ha_bkt; \ - (head)->hh.tbl->num_items++; \ - HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ - HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], hh, &(add)->hh, oomed); \ - if (oomed) { \ - HASH_ROLLBACK_BKT(hh, head, &(add)->hh); \ - HASH_DELETE_HH(hh, head, &(add)->hh); \ - (add)->hh.tbl = NULL; \ - uthash_nonfatal_oom(add); \ - } else { \ - HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ - HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ - } \ - } else { \ - (add)->hh.tbl = NULL; \ - uthash_nonfatal_oom(add); \ - } \ -} while (0) - -#else - -#define HASH_ADD_TO_TABLE(hh,head,keyptr,keylen_in,hashval,add,oomed) \ -do { \ - unsigned _ha_bkt; \ - (head)->hh.tbl->num_items++; \ - HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ - HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], hh, &(add)->hh, oomed); \ - HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ - HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ -} while (0) - -#endif - - -#define HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh,head,keyptr,keylen_in,hashval,add,cmpfcn) \ -do { \ - IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; ) \ - (add)->hh.hashv = (hashval); \ - (add)->hh.key = (char*) (keyptr); \ - (add)->hh.keylen = (unsigned) (keylen_in); \ - if (!(head)) { \ - (add)->hh.next = NULL; \ - (add)->hh.prev = NULL; \ - HASH_MAKE_TABLE(hh, add, _ha_oomed); \ - IF_HASH_NONFATAL_OOM( if (!_ha_oomed) { ) \ - (head) = (add); \ - IF_HASH_NONFATAL_OOM( } ) \ - } else { \ - void *_hs_iter = (head); \ - (add)->hh.tbl = (head)->hh.tbl; \ - HASH_AKBI_INNER_LOOP(hh, head, add, cmpfcn); \ - if (_hs_iter) { \ - (add)->hh.next = _hs_iter; \ - if (((add)->hh.prev = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev)) { \ - HH_FROM_ELMT((head)->hh.tbl, (add)->hh.prev)->next = (add); \ - } else { \ - (head) = (add); \ - } \ - HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev = (add); \ - } else { \ - HASH_APPEND_LIST(hh, head, add); \ - } \ - } \ - HASH_ADD_TO_TABLE(hh, head, keyptr, keylen_in, hashval, add, _ha_oomed); \ - HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE_INORDER"); \ -} while (0) - -#define HASH_ADD_KEYPTR_INORDER(hh,head,keyptr,keylen_in,add,cmpfcn) \ -do { \ - unsigned _hs_hashv; \ - HASH_VALUE(keyptr, keylen_in, _hs_hashv); \ - HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, keyptr, keylen_in, _hs_hashv, add, cmpfcn); \ -} while (0) - -#define HASH_ADD_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,cmpfcn) \ - HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn) - -#define HASH_ADD_INORDER(hh,head,fieldname,keylen_in,add,cmpfcn) \ - HASH_ADD_KEYPTR_INORDER(hh, head, &((add)->fieldname), keylen_in, add, cmpfcn) - -#define HASH_ADD_KEYPTR_BYHASHVALUE(hh,head,keyptr,keylen_in,hashval,add) \ -do { \ - IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; ) \ - (add)->hh.hashv = (hashval); \ - (add)->hh.key = (const void*) (keyptr); \ - (add)->hh.keylen = (unsigned) (keylen_in); \ - if (!(head)) { \ - (add)->hh.next = NULL; \ - (add)->hh.prev = NULL; \ - HASH_MAKE_TABLE(hh, add, _ha_oomed); \ - IF_HASH_NONFATAL_OOM( if (!_ha_oomed) { ) \ - (head) = (add); \ - IF_HASH_NONFATAL_OOM( } ) \ - } else { \ - (add)->hh.tbl = (head)->hh.tbl; \ - HASH_APPEND_LIST(hh, head, add); \ - } \ - HASH_ADD_TO_TABLE(hh, head, keyptr, keylen_in, hashval, add, _ha_oomed); \ - HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE"); \ -} while (0) - -#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ -do { \ - unsigned _ha_hashv; \ - HASH_VALUE(keyptr, keylen_in, _ha_hashv); \ - HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, keyptr, keylen_in, _ha_hashv, add); \ -} while (0) - -#define HASH_ADD_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add) \ - HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add) - -#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ - HASH_ADD_KEYPTR(hh, head, &((add)->fieldname), keylen_in, add) - -#define HASH_TO_BKT(hashv,num_bkts,bkt) \ -do { \ - bkt = ((hashv) & ((num_bkts) - 1U)); \ -} while (0) - -/* delete "delptr" from the hash table. - * "the usual" patch-up process for the app-order doubly-linked-list. - * The use of _hd_hh_del below deserves special explanation. - * These used to be expressed using (delptr) but that led to a bug - * if someone used the same symbol for the head and deletee, like - * HASH_DELETE(hh,users,users); - * We want that to work, but by changing the head (users) below - * we were forfeiting our ability to further refer to the deletee (users) - * in the patch-up process. Solution: use scratch space to - * copy the deletee pointer, then the latter references are via that - * scratch pointer rather than through the repointed (users) symbol. - */ -#define HASH_DELETE(hh,head,delptr) \ - HASH_DELETE_HH(hh, head, &(delptr)->hh) - -#define HASH_DELETE_HH(hh,head,delptrhh) \ -do { \ - struct UT_hash_handle *_hd_hh_del = (delptrhh); \ - if ((_hd_hh_del->prev == NULL) && (_hd_hh_del->next == NULL)) { \ - HASH_BLOOM_FREE((head)->hh.tbl); \ - uthash_free((head)->hh.tbl->buckets, \ - (head)->hh.tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ - uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ - (head) = NULL; \ - } else { \ - unsigned _hd_bkt; \ - if (_hd_hh_del == (head)->hh.tbl->tail) { \ - (head)->hh.tbl->tail = HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev); \ - } \ - if (_hd_hh_del->prev != NULL) { \ - HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev)->next = _hd_hh_del->next; \ - } else { \ - DECLTYPE_ASSIGN(head, _hd_hh_del->next); \ - } \ - if (_hd_hh_del->next != NULL) { \ - HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->next)->prev = _hd_hh_del->prev; \ - } \ - HASH_TO_BKT(_hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ - HASH_DEL_IN_BKT((head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ - (head)->hh.tbl->num_items--; \ - } \ - HASH_FSCK(hh, head, "HASH_DELETE_HH"); \ -} while (0) - -/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ -#define HASH_FIND_STR(head,findstr,out) \ -do { \ - unsigned _uthash_hfstr_keylen = (unsigned)uthash_strlen(findstr); \ - HASH_FIND(hh, head, findstr, _uthash_hfstr_keylen, out); \ -} while (0) -#define HASH_ADD_STR(head,strfield,add) \ -do { \ - unsigned _uthash_hastr_keylen = (unsigned)uthash_strlen((add)->strfield); \ - HASH_ADD(hh, head, strfield[0], _uthash_hastr_keylen, add); \ -} while (0) -#define HASH_REPLACE_STR(head,strfield,add,replaced) \ -do { \ - unsigned _uthash_hrstr_keylen = (unsigned)uthash_strlen((add)->strfield); \ - HASH_REPLACE(hh, head, strfield[0], _uthash_hrstr_keylen, add, replaced); \ -} while (0) -#define HASH_FIND_INT(head,findint,out) \ - HASH_FIND(hh,head,findint,sizeof(int),out) -#define HASH_ADD_INT(head,intfield,add) \ - HASH_ADD(hh,head,intfield,sizeof(int),add) -#define HASH_REPLACE_INT(head,intfield,add,replaced) \ - HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced) -#define HASH_FIND_PTR(head,findptr,out) \ - HASH_FIND(hh,head,findptr,sizeof(void *),out) -#define HASH_ADD_PTR(head,ptrfield,add) \ - HASH_ADD(hh,head,ptrfield,sizeof(void *),add) -#define HASH_REPLACE_PTR(head,ptrfield,add,replaced) \ - HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) -#define HASH_DEL(head,delptr) \ - HASH_DELETE(hh,head,delptr) - -/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. - * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. - */ -#ifdef HASH_DEBUG -#include /* fprintf, stderr */ -#define HASH_OOPS(...) do { fprintf(stderr, __VA_ARGS__); exit(-1); } while (0) -#define HASH_FSCK(hh,head,where) \ -do { \ - struct UT_hash_handle *_thh; \ - if (head) { \ - unsigned _bkt_i; \ - unsigned _count = 0; \ - char *_prev; \ - for (_bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; ++_bkt_i) { \ - unsigned _bkt_count = 0; \ - _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ - _prev = NULL; \ - while (_thh) { \ - if (_prev != (char*)(_thh->hh_prev)) { \ - HASH_OOPS("%s: invalid hh_prev %p, actual %p\n", \ - (where), (void*)_thh->hh_prev, (void*)_prev); \ - } \ - _bkt_count++; \ - _prev = (char*)(_thh); \ - _thh = _thh->hh_next; \ - } \ - _count += _bkt_count; \ - if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ - HASH_OOPS("%s: invalid bucket count %u, actual %u\n", \ - (where), (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ - } \ - } \ - if (_count != (head)->hh.tbl->num_items) { \ - HASH_OOPS("%s: invalid hh item count %u, actual %u\n", \ - (where), (head)->hh.tbl->num_items, _count); \ - } \ - _count = 0; \ - _prev = NULL; \ - _thh = &(head)->hh; \ - while (_thh) { \ - _count++; \ - if (_prev != (char*)_thh->prev) { \ - HASH_OOPS("%s: invalid prev %p, actual %p\n", \ - (where), (void*)_thh->prev, (void*)_prev); \ - } \ - _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ - _thh = (_thh->next ? HH_FROM_ELMT((head)->hh.tbl, _thh->next) : NULL); \ - } \ - if (_count != (head)->hh.tbl->num_items) { \ - HASH_OOPS("%s: invalid app item count %u, actual %u\n", \ - (where), (head)->hh.tbl->num_items, _count); \ - } \ - } \ -} while (0) -#else -#define HASH_FSCK(hh,head,where) -#endif - -/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to - * the descriptor to which this macro is defined for tuning the hash function. - * The app can #include to get the prototype for write(2). */ -#ifdef HASH_EMIT_KEYS -#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ -do { \ - unsigned _klen = fieldlen; \ - write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ - write(HASH_EMIT_KEYS, keyptr, (unsigned long)fieldlen); \ -} while (0) -#else -#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) -#endif - -/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */ -#define HASH_BER(key,keylen,hashv) \ -do { \ - unsigned _hb_keylen = (unsigned)keylen; \ - const unsigned char *_hb_key = (const unsigned char*)(key); \ - (hashv) = 0; \ - while (_hb_keylen-- != 0U) { \ - (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; \ - } \ -} while (0) - - -/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at - * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ -#define HASH_SAX(key,keylen,hashv) \ -do { \ - unsigned _sx_i; \ - const unsigned char *_hs_key = (const unsigned char*)(key); \ - hashv = 0; \ - for (_sx_i=0; _sx_i < keylen; _sx_i++) { \ - hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ - } \ -} while (0) -/* FNV-1a variation */ -#define HASH_FNV(key,keylen,hashv) \ -do { \ - unsigned _fn_i; \ - const unsigned char *_hf_key = (const unsigned char*)(key); \ - (hashv) = 2166136261U; \ - for (_fn_i=0; _fn_i < keylen; _fn_i++) { \ - hashv = hashv ^ _hf_key[_fn_i]; \ - hashv = hashv * 16777619U; \ - } \ -} while (0) - -#define HASH_OAT(key,keylen,hashv) \ -do { \ - unsigned _ho_i; \ - const unsigned char *_ho_key=(const unsigned char*)(key); \ - hashv = 0; \ - for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ - hashv += _ho_key[_ho_i]; \ - hashv += (hashv << 10); \ - hashv ^= (hashv >> 6); \ - } \ - hashv += (hashv << 3); \ - hashv ^= (hashv >> 11); \ - hashv += (hashv << 15); \ -} while (0) - -#define HASH_JEN_MIX(a,b,c) \ -do { \ - a -= b; a -= c; a ^= ( c >> 13 ); \ - b -= c; b -= a; b ^= ( a << 8 ); \ - c -= a; c -= b; c ^= ( b >> 13 ); \ - a -= b; a -= c; a ^= ( c >> 12 ); \ - b -= c; b -= a; b ^= ( a << 16 ); \ - c -= a; c -= b; c ^= ( b >> 5 ); \ - a -= b; a -= c; a ^= ( c >> 3 ); \ - b -= c; b -= a; b ^= ( a << 10 ); \ - c -= a; c -= b; c ^= ( b >> 15 ); \ -} while (0) - -#define HASH_JEN(key,keylen,hashv) \ -do { \ - unsigned _hj_i,_hj_j,_hj_k; \ - unsigned const char *_hj_key=(unsigned const char*)(key); \ - hashv = 0xfeedbeefu; \ - _hj_i = _hj_j = 0x9e3779b9u; \ - _hj_k = (unsigned)(keylen); \ - while (_hj_k >= 12U) { \ - _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ - + ( (unsigned)_hj_key[2] << 16 ) \ - + ( (unsigned)_hj_key[3] << 24 ) ); \ - _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ - + ( (unsigned)_hj_key[6] << 16 ) \ - + ( (unsigned)_hj_key[7] << 24 ) ); \ - hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ - + ( (unsigned)_hj_key[10] << 16 ) \ - + ( (unsigned)_hj_key[11] << 24 ) ); \ - \ - HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ - \ - _hj_key += 12; \ - _hj_k -= 12U; \ - } \ - hashv += (unsigned)(keylen); \ - switch ( _hj_k ) { \ - case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); /* FALLTHROUGH */ \ - case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); /* FALLTHROUGH */ \ - case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); /* FALLTHROUGH */ \ - case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); /* FALLTHROUGH */ \ - case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); /* FALLTHROUGH */ \ - case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); /* FALLTHROUGH */ \ - case 5: _hj_j += _hj_key[4]; /* FALLTHROUGH */ \ - case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); /* FALLTHROUGH */ \ - case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); /* FALLTHROUGH */ \ - case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); /* FALLTHROUGH */ \ - case 1: _hj_i += _hj_key[0]; /* FALLTHROUGH */ \ - default: ; \ - } \ - HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ -} while (0) - -/* The Paul Hsieh hash function */ -#undef get16bits -#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ - || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) -#define get16bits(d) (*((const uint16_t *) (d))) -#endif - -#if !defined (get16bits) -#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ - +(uint32_t)(((const uint8_t *)(d))[0]) ) -#endif -#define HASH_SFH(key,keylen,hashv) \ -do { \ - unsigned const char *_sfh_key=(unsigned const char*)(key); \ - uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen; \ - \ - unsigned _sfh_rem = _sfh_len & 3U; \ - _sfh_len >>= 2; \ - hashv = 0xcafebabeu; \ - \ - /* Main loop */ \ - for (;_sfh_len > 0U; _sfh_len--) { \ - hashv += get16bits (_sfh_key); \ - _sfh_tmp = ((uint32_t)(get16bits (_sfh_key+2)) << 11) ^ hashv; \ - hashv = (hashv << 16) ^ _sfh_tmp; \ - _sfh_key += 2U*sizeof (uint16_t); \ - hashv += hashv >> 11; \ - } \ - \ - /* Handle end cases */ \ - switch (_sfh_rem) { \ - case 3: hashv += get16bits (_sfh_key); \ - hashv ^= hashv << 16; \ - hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)]) << 18; \ - hashv += hashv >> 11; \ - break; \ - case 2: hashv += get16bits (_sfh_key); \ - hashv ^= hashv << 11; \ - hashv += hashv >> 17; \ - break; \ - case 1: hashv += *_sfh_key; \ - hashv ^= hashv << 10; \ - hashv += hashv >> 1; \ - break; \ - default: ; \ - } \ - \ - /* Force "avalanching" of final 127 bits */ \ - hashv ^= hashv << 3; \ - hashv += hashv >> 5; \ - hashv ^= hashv << 4; \ - hashv += hashv >> 17; \ - hashv ^= hashv << 25; \ - hashv += hashv >> 6; \ -} while (0) - -/* iterate over items in a known bucket to find desired item */ -#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,hashval,out) \ -do { \ - if ((head).hh_head != NULL) { \ - DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (head).hh_head)); \ - } else { \ - (out) = NULL; \ - } \ - while ((out) != NULL) { \ - if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) { \ - if (HASH_KEYCMP((out)->hh.key, keyptr, keylen_in) == 0) { \ - break; \ - } \ - } \ - if ((out)->hh.hh_next != NULL) { \ - DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (out)->hh.hh_next)); \ - } else { \ - (out) = NULL; \ - } \ - } \ -} while (0) - -/* add an item to a bucket */ -#define HASH_ADD_TO_BKT(head,hh,addhh,oomed) \ -do { \ - UT_hash_bucket *_ha_head = &(head); \ - _ha_head->count++; \ - (addhh)->hh_next = _ha_head->hh_head; \ - (addhh)->hh_prev = NULL; \ - if (_ha_head->hh_head != NULL) { \ - _ha_head->hh_head->hh_prev = (addhh); \ - } \ - _ha_head->hh_head = (addhh); \ - if ((_ha_head->count >= ((_ha_head->expand_mult + 1U) * HASH_BKT_CAPACITY_THRESH)) \ - && !(addhh)->tbl->noexpand) { \ - HASH_EXPAND_BUCKETS(addhh,(addhh)->tbl, oomed); \ - IF_HASH_NONFATAL_OOM( \ - if (oomed) { \ - HASH_DEL_IN_BKT(head,addhh); \ - } \ - ) \ - } \ -} while (0) - -/* remove an item from a given bucket */ -#define HASH_DEL_IN_BKT(head,delhh) \ -do { \ - UT_hash_bucket *_hd_head = &(head); \ - _hd_head->count--; \ - if (_hd_head->hh_head == (delhh)) { \ - _hd_head->hh_head = (delhh)->hh_next; \ - } \ - if ((delhh)->hh_prev) { \ - (delhh)->hh_prev->hh_next = (delhh)->hh_next; \ - } \ - if ((delhh)->hh_next) { \ - (delhh)->hh_next->hh_prev = (delhh)->hh_prev; \ - } \ -} while (0) - -/* Bucket expansion has the effect of doubling the number of buckets - * and redistributing the items into the new buckets. Ideally the - * items will distribute more or less evenly into the new buckets - * (the extent to which this is true is a measure of the quality of - * the hash function as it applies to the key domain). - * - * With the items distributed into more buckets, the chain length - * (item count) in each bucket is reduced. Thus by expanding buckets - * the hash keeps a bound on the chain length. This bounded chain - * length is the essence of how a hash provides constant time lookup. - * - * The calculation of tbl->ideal_chain_maxlen below deserves some - * explanation. First, keep in mind that we're calculating the ideal - * maximum chain length based on the *new* (doubled) bucket count. - * In fractions this is just n/b (n=number of items,b=new num buckets). - * Since the ideal chain length is an integer, we want to calculate - * ceil(n/b). We don't depend on floating point arithmetic in this - * hash, so to calculate ceil(n/b) with integers we could write - * - * ceil(n/b) = (n/b) + ((n%b)?1:0) - * - * and in fact a previous version of this hash did just that. - * But now we have improved things a bit by recognizing that b is - * always a power of two. We keep its base 2 log handy (call it lb), - * so now we can write this with a bit shift and logical AND: - * - * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) - * - */ -#define HASH_EXPAND_BUCKETS(hh,tbl,oomed) \ -do { \ - unsigned _he_bkt; \ - unsigned _he_bkt_i; \ - struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ - UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ - _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ - sizeof(struct UT_hash_bucket) * (tbl)->num_buckets * 2U); \ - if (!_he_new_buckets) { \ - HASH_RECORD_OOM(oomed); \ - } else { \ - uthash_bzero(_he_new_buckets, \ - sizeof(struct UT_hash_bucket) * (tbl)->num_buckets * 2U); \ - (tbl)->ideal_chain_maxlen = \ - ((tbl)->num_items >> ((tbl)->log2_num_buckets+1U)) + \ - ((((tbl)->num_items & (((tbl)->num_buckets*2U)-1U)) != 0U) ? 1U : 0U); \ - (tbl)->nonideal_items = 0; \ - for (_he_bkt_i = 0; _he_bkt_i < (tbl)->num_buckets; _he_bkt_i++) { \ - _he_thh = (tbl)->buckets[ _he_bkt_i ].hh_head; \ - while (_he_thh != NULL) { \ - _he_hh_nxt = _he_thh->hh_next; \ - HASH_TO_BKT(_he_thh->hashv, (tbl)->num_buckets * 2U, _he_bkt); \ - _he_newbkt = &(_he_new_buckets[_he_bkt]); \ - if (++(_he_newbkt->count) > (tbl)->ideal_chain_maxlen) { \ - (tbl)->nonideal_items++; \ - if (_he_newbkt->count > _he_newbkt->expand_mult * (tbl)->ideal_chain_maxlen) { \ - _he_newbkt->expand_mult++; \ - } \ - } \ - _he_thh->hh_prev = NULL; \ - _he_thh->hh_next = _he_newbkt->hh_head; \ - if (_he_newbkt->hh_head != NULL) { \ - _he_newbkt->hh_head->hh_prev = _he_thh; \ - } \ - _he_newbkt->hh_head = _he_thh; \ - _he_thh = _he_hh_nxt; \ - } \ - } \ - uthash_free((tbl)->buckets, (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ - (tbl)->num_buckets *= 2U; \ - (tbl)->log2_num_buckets++; \ - (tbl)->buckets = _he_new_buckets; \ - (tbl)->ineff_expands = ((tbl)->nonideal_items > ((tbl)->num_items >> 1)) ? \ - ((tbl)->ineff_expands+1U) : 0U; \ - if ((tbl)->ineff_expands > 1U) { \ - (tbl)->noexpand = 1; \ - uthash_noexpand_fyi(tbl); \ - } \ - uthash_expand_fyi(tbl); \ - } \ -} while (0) - - -/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ -/* Note that HASH_SORT assumes the hash handle name to be hh. - * HASH_SRT was added to allow the hash handle name to be passed in. */ -#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) -#define HASH_SRT(hh,head,cmpfcn) \ -do { \ - unsigned _hs_i; \ - unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ - struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ - if (head != NULL) { \ - _hs_insize = 1; \ - _hs_looping = 1; \ - _hs_list = &((head)->hh); \ - while (_hs_looping != 0U) { \ - _hs_p = _hs_list; \ - _hs_list = NULL; \ - _hs_tail = NULL; \ - _hs_nmerges = 0; \ - while (_hs_p != NULL) { \ - _hs_nmerges++; \ - _hs_q = _hs_p; \ - _hs_psize = 0; \ - for (_hs_i = 0; _hs_i < _hs_insize; ++_hs_i) { \ - _hs_psize++; \ - _hs_q = ((_hs_q->next != NULL) ? \ - HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ - if (_hs_q == NULL) { \ - break; \ - } \ - } \ - _hs_qsize = _hs_insize; \ - while ((_hs_psize != 0U) || ((_hs_qsize != 0U) && (_hs_q != NULL))) { \ - if (_hs_psize == 0U) { \ - _hs_e = _hs_q; \ - _hs_q = ((_hs_q->next != NULL) ? \ - HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ - _hs_qsize--; \ - } else if ((_hs_qsize == 0U) || (_hs_q == NULL)) { \ - _hs_e = _hs_p; \ - if (_hs_p != NULL) { \ - _hs_p = ((_hs_p->next != NULL) ? \ - HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ - } \ - _hs_psize--; \ - } else if ((cmpfcn( \ - DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_p)), \ - DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_q)) \ - )) <= 0) { \ - _hs_e = _hs_p; \ - if (_hs_p != NULL) { \ - _hs_p = ((_hs_p->next != NULL) ? \ - HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ - } \ - _hs_psize--; \ - } else { \ - _hs_e = _hs_q; \ - _hs_q = ((_hs_q->next != NULL) ? \ - HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ - _hs_qsize--; \ - } \ - if ( _hs_tail != NULL ) { \ - _hs_tail->next = ((_hs_e != NULL) ? \ - ELMT_FROM_HH((head)->hh.tbl, _hs_e) : NULL); \ - } else { \ - _hs_list = _hs_e; \ - } \ - if (_hs_e != NULL) { \ - _hs_e->prev = ((_hs_tail != NULL) ? \ - ELMT_FROM_HH((head)->hh.tbl, _hs_tail) : NULL); \ - } \ - _hs_tail = _hs_e; \ - } \ - _hs_p = _hs_q; \ - } \ - if (_hs_tail != NULL) { \ - _hs_tail->next = NULL; \ - } \ - if (_hs_nmerges <= 1U) { \ - _hs_looping = 0; \ - (head)->hh.tbl->tail = _hs_tail; \ - DECLTYPE_ASSIGN(head, ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ - } \ - _hs_insize *= 2U; \ - } \ - HASH_FSCK(hh, head, "HASH_SRT"); \ - } \ -} while (0) - -/* This function selects items from one hash into another hash. - * The end result is that the selected items have dual presence - * in both hashes. There is no copy of the items made; rather - * they are added into the new hash through a secondary hash - * hash handle that must be present in the structure. */ -#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ -do { \ - unsigned _src_bkt, _dst_bkt; \ - void *_last_elt = NULL, *_elt; \ - UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ - ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ - if ((src) != NULL) { \ - for (_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ - for (_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ - _src_hh != NULL; \ - _src_hh = _src_hh->hh_next) { \ - _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ - if (cond(_elt)) { \ - IF_HASH_NONFATAL_OOM( int _hs_oomed = 0; ) \ - _dst_hh = (UT_hash_handle*)(void*)(((char*)_elt) + _dst_hho); \ - _dst_hh->key = _src_hh->key; \ - _dst_hh->keylen = _src_hh->keylen; \ - _dst_hh->hashv = _src_hh->hashv; \ - _dst_hh->prev = _last_elt; \ - _dst_hh->next = NULL; \ - if (_last_elt_hh != NULL) { \ - _last_elt_hh->next = _elt; \ - } \ - if ((dst) == NULL) { \ - DECLTYPE_ASSIGN(dst, _elt); \ - HASH_MAKE_TABLE(hh_dst, dst, _hs_oomed); \ - IF_HASH_NONFATAL_OOM( \ - if (_hs_oomed) { \ - uthash_nonfatal_oom(_elt); \ - (dst) = NULL; \ - continue; \ - } \ - ) \ - } else { \ - _dst_hh->tbl = (dst)->hh_dst.tbl; \ - } \ - HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ - HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt], hh_dst, _dst_hh, _hs_oomed); \ - (dst)->hh_dst.tbl->num_items++; \ - IF_HASH_NONFATAL_OOM( \ - if (_hs_oomed) { \ - HASH_ROLLBACK_BKT(hh_dst, dst, _dst_hh); \ - HASH_DELETE_HH(hh_dst, dst, _dst_hh); \ - _dst_hh->tbl = NULL; \ - uthash_nonfatal_oom(_elt); \ - continue; \ - } \ - ) \ - HASH_BLOOM_ADD(_dst_hh->tbl, _dst_hh->hashv); \ - _last_elt = _elt; \ - _last_elt_hh = _dst_hh; \ - } \ - } \ - } \ - } \ - HASH_FSCK(hh_dst, dst, "HASH_SELECT"); \ -} while (0) - -#define HASH_CLEAR(hh,head) \ -do { \ - if ((head) != NULL) { \ - HASH_BLOOM_FREE((head)->hh.tbl); \ - uthash_free((head)->hh.tbl->buckets, \ - (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ - uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ - (head) = NULL; \ - } \ -} while (0) - -#define HASH_OVERHEAD(hh,head) \ - (((head) != NULL) ? ( \ - (size_t)(((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ - ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ - sizeof(UT_hash_table) + \ - (HASH_BLOOM_BYTELEN))) : 0U) - -#ifdef NO_DECLTYPE -#define HASH_ITER(hh,head,el,tmp) \ -for(((el)=(head)), ((*(char**)(&(tmp)))=(char*)((head!=NULL)?(head)->hh.next:NULL)); \ - (el) != NULL; ((el)=(tmp)), ((*(char**)(&(tmp)))=(char*)((tmp!=NULL)?(tmp)->hh.next:NULL))) -#else -#define HASH_ITER(hh,head,el,tmp) \ -for(((el)=(head)), ((tmp)=DECLTYPE(el)((head!=NULL)?(head)->hh.next:NULL)); \ - (el) != NULL; ((el)=(tmp)), ((tmp)=DECLTYPE(el)((tmp!=NULL)?(tmp)->hh.next:NULL))) -#endif - -/* obtain a count of items in the hash */ -#define HASH_COUNT(head) HASH_CNT(hh,head) -#define HASH_CNT(hh,head) ((head != NULL)?((head)->hh.tbl->num_items):0U) - -typedef struct UT_hash_bucket { - struct UT_hash_handle *hh_head; - unsigned count; - - /* expand_mult is normally set to 0. In this situation, the max chain length - * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If - * the bucket's chain exceeds this length, bucket expansion is triggered). - * However, setting expand_mult to a non-zero value delays bucket expansion - * (that would be triggered by additions to this particular bucket) - * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. - * (The multiplier is simply expand_mult+1). The whole idea of this - * multiplier is to reduce bucket expansions, since they are expensive, in - * situations where we know that a particular bucket tends to be overused. - * It is better to let its chain length grow to a longer yet-still-bounded - * value, than to do an O(n) bucket expansion too often. - */ - unsigned expand_mult; - -} UT_hash_bucket; - -/* random signature used only to find hash tables in external analysis */ -#define HASH_SIGNATURE 0xa0111fe1u -#define HASH_BLOOM_SIGNATURE 0xb12220f2u - -typedef struct UT_hash_table { - UT_hash_bucket *buckets; - unsigned num_buckets, log2_num_buckets; - unsigned num_items; - struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ - ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ - - /* in an ideal situation (all buckets used equally), no bucket would have - * more than ceil(#items/#buckets) items. that's the ideal chain length. */ - unsigned ideal_chain_maxlen; - - /* nonideal_items is the number of items in the hash whose chain position - * exceeds the ideal chain maxlen. these items pay the penalty for an uneven - * hash distribution; reaching them in a chain traversal takes >ideal steps */ - unsigned nonideal_items; - - /* ineffective expands occur when a bucket doubling was performed, but - * afterward, more than half the items in the hash had nonideal chain - * positions. If this happens on two consecutive expansions we inhibit any - * further expansion, as it's not helping; this happens when the hash - * function isn't a good fit for the key domain. When expansion is inhibited - * the hash will still work, albeit no longer in constant time. */ - unsigned ineff_expands, noexpand; - - uint32_t signature; /* used only to find hash tables in external analysis */ -#ifdef HASH_BLOOM - uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ - uint8_t *bloom_bv; - uint8_t bloom_nbits; -#endif - -} UT_hash_table; - -typedef struct UT_hash_handle { - struct UT_hash_table *tbl; - void *prev; /* prev element in app order */ - void *next; /* next element in app order */ - struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ - struct UT_hash_handle *hh_next; /* next hh in bucket order */ - const void *key; /* ptr to enclosing struct's key */ - unsigned keylen; /* enclosing struct's key len */ - unsigned hashv; /* result of hash-fcn(key) */ -} UT_hash_handle; - -#endif /* UTHASH_H */ diff --git a/test/http_decoder/uthash-2.3.0/include/utlist.h b/test/http_decoder/uthash-2.3.0/include/utlist.h deleted file mode 100644 index 6230a67..0000000 --- a/test/http_decoder/uthash-2.3.0/include/utlist.h +++ /dev/null @@ -1,1073 +0,0 @@ -/* -Copyright (c) 2007-2021, Troy D. Hanson http://troydhanson.github.com/uthash/ -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef UTLIST_H -#define UTLIST_H - -#define UTLIST_VERSION 2.3.0 - -#include - -/* - * This file contains macros to manipulate singly and doubly-linked lists. - * - * 1. LL_ macros: singly-linked lists. - * 2. DL_ macros: doubly-linked lists. - * 3. CDL_ macros: circular doubly-linked lists. - * - * To use singly-linked lists, your structure must have a "next" pointer. - * To use doubly-linked lists, your structure must "prev" and "next" pointers. - * Either way, the pointer to the head of the list must be initialized to NULL. - * - * ----------------.EXAMPLE ------------------------- - * struct item { - * int id; - * struct item *prev, *next; - * } - * - * struct item *list = NULL: - * - * int main() { - * struct item *item; - * ... allocate and populate item ... - * DL_APPEND(list, item); - * } - * -------------------------------------------------- - * - * For doubly-linked lists, the append and delete macros are O(1) - * For singly-linked lists, append and delete are O(n) but prepend is O(1) - * The sort macro is O(n log(n)) for all types of single/double/circular lists. - */ - -/* These macros use decltype or the earlier __typeof GNU extension. - As decltype is only available in newer compilers (VS2010 or gcc 4.3+ - when compiling c++ source) this code uses whatever method is needed - or, for VS2008 where neither is available, uses casting workarounds. */ -#if !defined(LDECLTYPE) && !defined(NO_DECLTYPE) -#if defined(_MSC_VER) /* MS compiler */ -#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ -#define LDECLTYPE(x) decltype(x) -#else /* VS2008 or older (or VS2010 in C mode) */ -#define NO_DECLTYPE -#endif -#elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) -#define NO_DECLTYPE -#else /* GNU, Sun and other compilers */ -#define LDECLTYPE(x) __typeof(x) -#endif -#endif - -/* for VS2008 we use some workarounds to get around the lack of decltype, - * namely, we always reassign our tmp variable to the list head if we need - * to dereference its prev/next pointers, and save/restore the real head.*/ -#ifdef NO_DECLTYPE -#define IF_NO_DECLTYPE(x) x -#define LDECLTYPE(x) char* -#define UTLIST_SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); } -#define UTLIST_NEXT(elt,list,next) ((char*)((list)->next)) -#define UTLIST_NEXTASGN(elt,list,to,next) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); } -/* #define UTLIST_PREV(elt,list,prev) ((char*)((list)->prev)) */ -#define UTLIST_PREVASGN(elt,list,to,prev) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); } -#define UTLIST_RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; } -#define UTLIST_CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); } -#else -#define IF_NO_DECLTYPE(x) -#define UTLIST_SV(elt,list) -#define UTLIST_NEXT(elt,list,next) ((elt)->next) -#define UTLIST_NEXTASGN(elt,list,to,next) ((elt)->next)=(to) -/* #define UTLIST_PREV(elt,list,prev) ((elt)->prev) */ -#define UTLIST_PREVASGN(elt,list,to,prev) ((elt)->prev)=(to) -#define UTLIST_RS(list) -#define UTLIST_CASTASGN(a,b) (a)=(b) -#endif - -/****************************************************************************** - * The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort * - * Unwieldy variable names used here to avoid shadowing passed-in variables. * - *****************************************************************************/ -#define LL_SORT(list, cmp) \ - LL_SORT2(list, cmp, next) - -#define LL_SORT2(list, cmp, next) \ -do { \ - LDECLTYPE(list) _ls_p; \ - LDECLTYPE(list) _ls_q; \ - LDECLTYPE(list) _ls_e; \ - LDECLTYPE(list) _ls_tail; \ - IF_NO_DECLTYPE(LDECLTYPE(list) _tmp;) \ - int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ - if (list) { \ - _ls_insize = 1; \ - _ls_looping = 1; \ - while (_ls_looping) { \ - UTLIST_CASTASGN(_ls_p,list); \ - (list) = NULL; \ - _ls_tail = NULL; \ - _ls_nmerges = 0; \ - while (_ls_p) { \ - _ls_nmerges++; \ - _ls_q = _ls_p; \ - _ls_psize = 0; \ - for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ - _ls_psize++; \ - UTLIST_SV(_ls_q,list); _ls_q = UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); \ - if (!_ls_q) break; \ - } \ - _ls_qsize = _ls_insize; \ - while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ - if (_ls_psize == 0) { \ - _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ - UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ - } else if (_ls_qsize == 0 || !_ls_q) { \ - _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ - UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ - } else if (cmp(_ls_p,_ls_q) <= 0) { \ - _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ - UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ - } else { \ - _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ - UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ - } \ - if (_ls_tail) { \ - UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_ls_e,next); UTLIST_RS(list); \ - } else { \ - UTLIST_CASTASGN(list,_ls_e); \ - } \ - _ls_tail = _ls_e; \ - } \ - _ls_p = _ls_q; \ - } \ - if (_ls_tail) { \ - UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,NULL,next); UTLIST_RS(list); \ - } \ - if (_ls_nmerges <= 1) { \ - _ls_looping=0; \ - } \ - _ls_insize *= 2; \ - } \ - } \ -} while (0) - - -#define DL_SORT(list, cmp) \ - DL_SORT2(list, cmp, prev, next) - -#define DL_SORT2(list, cmp, prev, next) \ -do { \ - LDECLTYPE(list) _ls_p; \ - LDECLTYPE(list) _ls_q; \ - LDECLTYPE(list) _ls_e; \ - LDECLTYPE(list) _ls_tail; \ - IF_NO_DECLTYPE(LDECLTYPE(list) _tmp;) \ - int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ - if (list) { \ - _ls_insize = 1; \ - _ls_looping = 1; \ - while (_ls_looping) { \ - UTLIST_CASTASGN(_ls_p,list); \ - (list) = NULL; \ - _ls_tail = NULL; \ - _ls_nmerges = 0; \ - while (_ls_p) { \ - _ls_nmerges++; \ - _ls_q = _ls_p; \ - _ls_psize = 0; \ - for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ - _ls_psize++; \ - UTLIST_SV(_ls_q,list); _ls_q = UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); \ - if (!_ls_q) break; \ - } \ - _ls_qsize = _ls_insize; \ - while ((_ls_psize > 0) || ((_ls_qsize > 0) && _ls_q)) { \ - if (_ls_psize == 0) { \ - _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ - UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ - } else if ((_ls_qsize == 0) || (!_ls_q)) { \ - _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ - UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ - } else if (cmp(_ls_p,_ls_q) <= 0) { \ - _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ - UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ - } else { \ - _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ - UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ - } \ - if (_ls_tail) { \ - UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_ls_e,next); UTLIST_RS(list); \ - } else { \ - UTLIST_CASTASGN(list,_ls_e); \ - } \ - UTLIST_SV(_ls_e,list); UTLIST_PREVASGN(_ls_e,list,_ls_tail,prev); UTLIST_RS(list); \ - _ls_tail = _ls_e; \ - } \ - _ls_p = _ls_q; \ - } \ - UTLIST_CASTASGN((list)->prev, _ls_tail); \ - UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,NULL,next); UTLIST_RS(list); \ - if (_ls_nmerges <= 1) { \ - _ls_looping=0; \ - } \ - _ls_insize *= 2; \ - } \ - } \ -} while (0) - -#define CDL_SORT(list, cmp) \ - CDL_SORT2(list, cmp, prev, next) - -#define CDL_SORT2(list, cmp, prev, next) \ -do { \ - LDECLTYPE(list) _ls_p; \ - LDECLTYPE(list) _ls_q; \ - LDECLTYPE(list) _ls_e; \ - LDECLTYPE(list) _ls_tail; \ - LDECLTYPE(list) _ls_oldhead; \ - LDECLTYPE(list) _tmp; \ - int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ - if (list) { \ - _ls_insize = 1; \ - _ls_looping = 1; \ - while (_ls_looping) { \ - UTLIST_CASTASGN(_ls_p,list); \ - UTLIST_CASTASGN(_ls_oldhead,list); \ - (list) = NULL; \ - _ls_tail = NULL; \ - _ls_nmerges = 0; \ - while (_ls_p) { \ - _ls_nmerges++; \ - _ls_q = _ls_p; \ - _ls_psize = 0; \ - for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ - _ls_psize++; \ - UTLIST_SV(_ls_q,list); \ - if (UTLIST_NEXT(_ls_q,list,next) == _ls_oldhead) { \ - _ls_q = NULL; \ - } else { \ - _ls_q = UTLIST_NEXT(_ls_q,list,next); \ - } \ - UTLIST_RS(list); \ - if (!_ls_q) break; \ - } \ - _ls_qsize = _ls_insize; \ - while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ - if (_ls_psize == 0) { \ - _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ - UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ - if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ - } else if (_ls_qsize == 0 || !_ls_q) { \ - _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ - UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ - if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ - } else if (cmp(_ls_p,_ls_q) <= 0) { \ - _ls_e = _ls_p; UTLIST_SV(_ls_p,list); _ls_p = \ - UTLIST_NEXT(_ls_p,list,next); UTLIST_RS(list); _ls_psize--; \ - if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ - } else { \ - _ls_e = _ls_q; UTLIST_SV(_ls_q,list); _ls_q = \ - UTLIST_NEXT(_ls_q,list,next); UTLIST_RS(list); _ls_qsize--; \ - if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ - } \ - if (_ls_tail) { \ - UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_ls_e,next); UTLIST_RS(list); \ - } else { \ - UTLIST_CASTASGN(list,_ls_e); \ - } \ - UTLIST_SV(_ls_e,list); UTLIST_PREVASGN(_ls_e,list,_ls_tail,prev); UTLIST_RS(list); \ - _ls_tail = _ls_e; \ - } \ - _ls_p = _ls_q; \ - } \ - UTLIST_CASTASGN((list)->prev,_ls_tail); \ - UTLIST_CASTASGN(_tmp,list); \ - UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,_tmp,next); UTLIST_RS(list); \ - if (_ls_nmerges <= 1) { \ - _ls_looping=0; \ - } \ - _ls_insize *= 2; \ - } \ - } \ -} while (0) - -/****************************************************************************** - * singly linked list macros (non-circular) * - *****************************************************************************/ -#define LL_PREPEND(head,add) \ - LL_PREPEND2(head,add,next) - -#define LL_PREPEND2(head,add,next) \ -do { \ - (add)->next = (head); \ - (head) = (add); \ -} while (0) - -#define LL_CONCAT(head1,head2) \ - LL_CONCAT2(head1,head2,next) - -#define LL_CONCAT2(head1,head2,next) \ -do { \ - LDECLTYPE(head1) _tmp; \ - if (head1) { \ - _tmp = (head1); \ - while (_tmp->next) { _tmp = _tmp->next; } \ - _tmp->next=(head2); \ - } else { \ - (head1)=(head2); \ - } \ -} while (0) - -#define LL_APPEND(head,add) \ - LL_APPEND2(head,add,next) - -#define LL_APPEND2(head,add,next) \ -do { \ - LDECLTYPE(head) _tmp; \ - (add)->next=NULL; \ - if (head) { \ - _tmp = (head); \ - while (_tmp->next) { _tmp = _tmp->next; } \ - _tmp->next=(add); \ - } else { \ - (head)=(add); \ - } \ -} while (0) - -#define LL_INSERT_INORDER(head,add,cmp) \ - LL_INSERT_INORDER2(head,add,cmp,next) - -#define LL_INSERT_INORDER2(head,add,cmp,next) \ -do { \ - LDECLTYPE(head) _tmp; \ - if (head) { \ - LL_LOWER_BOUND2(head, _tmp, add, cmp, next); \ - LL_APPEND_ELEM2(head, _tmp, add, next); \ - } else { \ - (head) = (add); \ - (head)->next = NULL; \ - } \ -} while (0) - -#define LL_LOWER_BOUND(head,elt,like,cmp) \ - LL_LOWER_BOUND2(head,elt,like,cmp,next) - -#define LL_LOWER_BOUND2(head,elt,like,cmp,next) \ - do { \ - if ((head) == NULL || (cmp(head, like)) >= 0) { \ - (elt) = NULL; \ - } else { \ - for ((elt) = (head); (elt)->next != NULL; (elt) = (elt)->next) { \ - if (cmp((elt)->next, like) >= 0) { \ - break; \ - } \ - } \ - } \ - } while (0) - -#define LL_DELETE(head,del) \ - LL_DELETE2(head,del,next) - -#define LL_DELETE2(head,del,next) \ -do { \ - LDECLTYPE(head) _tmp; \ - if ((head) == (del)) { \ - (head)=(head)->next; \ - } else { \ - _tmp = (head); \ - while (_tmp->next && (_tmp->next != (del))) { \ - _tmp = _tmp->next; \ - } \ - if (_tmp->next) { \ - _tmp->next = (del)->next; \ - } \ - } \ -} while (0) - -#define LL_COUNT(head,el,counter) \ - LL_COUNT2(head,el,counter,next) \ - -#define LL_COUNT2(head,el,counter,next) \ -do { \ - (counter) = 0; \ - LL_FOREACH2(head,el,next) { ++(counter); } \ -} while (0) - -#define LL_FOREACH(head,el) \ - LL_FOREACH2(head,el,next) - -#define LL_FOREACH2(head,el,next) \ - for ((el) = (head); el; (el) = (el)->next) - -#define LL_FOREACH_SAFE(head,el,tmp) \ - LL_FOREACH_SAFE2(head,el,tmp,next) - -#define LL_FOREACH_SAFE2(head,el,tmp,next) \ - for ((el) = (head); (el) && ((tmp) = (el)->next, 1); (el) = (tmp)) - -#define LL_SEARCH_SCALAR(head,out,field,val) \ - LL_SEARCH_SCALAR2(head,out,field,val,next) - -#define LL_SEARCH_SCALAR2(head,out,field,val,next) \ -do { \ - LL_FOREACH2(head,out,next) { \ - if ((out)->field == (val)) break; \ - } \ -} while (0) - -#define LL_SEARCH(head,out,elt,cmp) \ - LL_SEARCH2(head,out,elt,cmp,next) - -#define LL_SEARCH2(head,out,elt,cmp,next) \ -do { \ - LL_FOREACH2(head,out,next) { \ - if ((cmp(out,elt))==0) break; \ - } \ -} while (0) - -#define LL_REPLACE_ELEM2(head, el, add, next) \ -do { \ - LDECLTYPE(head) _tmp; \ - assert((head) != NULL); \ - assert((el) != NULL); \ - assert((add) != NULL); \ - (add)->next = (el)->next; \ - if ((head) == (el)) { \ - (head) = (add); \ - } else { \ - _tmp = (head); \ - while (_tmp->next && (_tmp->next != (el))) { \ - _tmp = _tmp->next; \ - } \ - if (_tmp->next) { \ - _tmp->next = (add); \ - } \ - } \ -} while (0) - -#define LL_REPLACE_ELEM(head, el, add) \ - LL_REPLACE_ELEM2(head, el, add, next) - -#define LL_PREPEND_ELEM2(head, el, add, next) \ -do { \ - if (el) { \ - LDECLTYPE(head) _tmp; \ - assert((head) != NULL); \ - assert((add) != NULL); \ - (add)->next = (el); \ - if ((head) == (el)) { \ - (head) = (add); \ - } else { \ - _tmp = (head); \ - while (_tmp->next && (_tmp->next != (el))) { \ - _tmp = _tmp->next; \ - } \ - if (_tmp->next) { \ - _tmp->next = (add); \ - } \ - } \ - } else { \ - LL_APPEND2(head, add, next); \ - } \ -} while (0) \ - -#define LL_PREPEND_ELEM(head, el, add) \ - LL_PREPEND_ELEM2(head, el, add, next) - -#define LL_APPEND_ELEM2(head, el, add, next) \ -do { \ - if (el) { \ - assert((head) != NULL); \ - assert((add) != NULL); \ - (add)->next = (el)->next; \ - (el)->next = (add); \ - } else { \ - LL_PREPEND2(head, add, next); \ - } \ -} while (0) \ - -#define LL_APPEND_ELEM(head, el, add) \ - LL_APPEND_ELEM2(head, el, add, next) - -#ifdef NO_DECLTYPE -/* Here are VS2008 / NO_DECLTYPE replacements for a few functions */ - -#undef LL_CONCAT2 -#define LL_CONCAT2(head1,head2,next) \ -do { \ - char *_tmp; \ - if (head1) { \ - _tmp = (char*)(head1); \ - while ((head1)->next) { (head1) = (head1)->next; } \ - (head1)->next = (head2); \ - UTLIST_RS(head1); \ - } else { \ - (head1)=(head2); \ - } \ -} while (0) - -#undef LL_APPEND2 -#define LL_APPEND2(head,add,next) \ -do { \ - if (head) { \ - (add)->next = head; /* use add->next as a temp variable */ \ - while ((add)->next->next) { (add)->next = (add)->next->next; } \ - (add)->next->next=(add); \ - } else { \ - (head)=(add); \ - } \ - (add)->next=NULL; \ -} while (0) - -#undef LL_INSERT_INORDER2 -#define LL_INSERT_INORDER2(head,add,cmp,next) \ -do { \ - if ((head) == NULL || (cmp(head, add)) >= 0) { \ - (add)->next = (head); \ - (head) = (add); \ - } else { \ - char *_tmp = (char*)(head); \ - while ((head)->next != NULL && (cmp((head)->next, add)) < 0) { \ - (head) = (head)->next; \ - } \ - (add)->next = (head)->next; \ - (head)->next = (add); \ - UTLIST_RS(head); \ - } \ -} while (0) - -#undef LL_DELETE2 -#define LL_DELETE2(head,del,next) \ -do { \ - if ((head) == (del)) { \ - (head)=(head)->next; \ - } else { \ - char *_tmp = (char*)(head); \ - while ((head)->next && ((head)->next != (del))) { \ - (head) = (head)->next; \ - } \ - if ((head)->next) { \ - (head)->next = ((del)->next); \ - } \ - UTLIST_RS(head); \ - } \ -} while (0) - -#undef LL_REPLACE_ELEM2 -#define LL_REPLACE_ELEM2(head, el, add, next) \ -do { \ - assert((head) != NULL); \ - assert((el) != NULL); \ - assert((add) != NULL); \ - if ((head) == (el)) { \ - (head) = (add); \ - } else { \ - (add)->next = head; \ - while ((add)->next->next && ((add)->next->next != (el))) { \ - (add)->next = (add)->next->next; \ - } \ - if ((add)->next->next) { \ - (add)->next->next = (add); \ - } \ - } \ - (add)->next = (el)->next; \ -} while (0) - -#undef LL_PREPEND_ELEM2 -#define LL_PREPEND_ELEM2(head, el, add, next) \ -do { \ - if (el) { \ - assert((head) != NULL); \ - assert((add) != NULL); \ - if ((head) == (el)) { \ - (head) = (add); \ - } else { \ - (add)->next = (head); \ - while ((add)->next->next && ((add)->next->next != (el))) { \ - (add)->next = (add)->next->next; \ - } \ - if ((add)->next->next) { \ - (add)->next->next = (add); \ - } \ - } \ - (add)->next = (el); \ - } else { \ - LL_APPEND2(head, add, next); \ - } \ -} while (0) \ - -#endif /* NO_DECLTYPE */ - -/****************************************************************************** - * doubly linked list macros (non-circular) * - *****************************************************************************/ -#define DL_PREPEND(head,add) \ - DL_PREPEND2(head,add,prev,next) - -#define DL_PREPEND2(head,add,prev,next) \ -do { \ - (add)->next = (head); \ - if (head) { \ - (add)->prev = (head)->prev; \ - (head)->prev = (add); \ - } else { \ - (add)->prev = (add); \ - } \ - (head) = (add); \ -} while (0) - -#define DL_APPEND(head,add) \ - DL_APPEND2(head,add,prev,next) - -#define DL_APPEND2(head,add,prev,next) \ -do { \ - if (head) { \ - (add)->prev = (head)->prev; \ - (head)->prev->next = (add); \ - (head)->prev = (add); \ - (add)->next = NULL; \ - } else { \ - (head)=(add); \ - (head)->prev = (head); \ - (head)->next = NULL; \ - } \ -} while (0) - -#define DL_INSERT_INORDER(head,add,cmp) \ - DL_INSERT_INORDER2(head,add,cmp,prev,next) - -#define DL_INSERT_INORDER2(head,add,cmp,prev,next) \ -do { \ - LDECLTYPE(head) _tmp; \ - if (head) { \ - DL_LOWER_BOUND2(head, _tmp, add, cmp, next); \ - DL_APPEND_ELEM2(head, _tmp, add, prev, next); \ - } else { \ - (head) = (add); \ - (head)->prev = (head); \ - (head)->next = NULL; \ - } \ -} while (0) - -#define DL_LOWER_BOUND(head,elt,like,cmp) \ - DL_LOWER_BOUND2(head,elt,like,cmp,next) - -#define DL_LOWER_BOUND2(head,elt,like,cmp,next) \ -do { \ - if ((head) == NULL || (cmp(head, like)) >= 0) { \ - (elt) = NULL; \ - } else { \ - for ((elt) = (head); (elt)->next != NULL; (elt) = (elt)->next) { \ - if ((cmp((elt)->next, like)) >= 0) { \ - break; \ - } \ - } \ - } \ -} while (0) - -#define DL_CONCAT(head1,head2) \ - DL_CONCAT2(head1,head2,prev,next) - -#define DL_CONCAT2(head1,head2,prev,next) \ -do { \ - LDECLTYPE(head1) _tmp; \ - if (head2) { \ - if (head1) { \ - UTLIST_CASTASGN(_tmp, (head2)->prev); \ - (head2)->prev = (head1)->prev; \ - (head1)->prev->next = (head2); \ - UTLIST_CASTASGN((head1)->prev, _tmp); \ - } else { \ - (head1)=(head2); \ - } \ - } \ -} while (0) - -#define DL_DELETE(head,del) \ - DL_DELETE2(head,del,prev,next) - -#define DL_DELETE2(head,del,prev,next) \ -do { \ - assert((head) != NULL); \ - assert((del)->prev != NULL); \ - if ((del)->prev == (del)) { \ - (head)=NULL; \ - } else if ((del)==(head)) { \ - (del)->next->prev = (del)->prev; \ - (head) = (del)->next; \ - } else { \ - (del)->prev->next = (del)->next; \ - if ((del)->next) { \ - (del)->next->prev = (del)->prev; \ - } else { \ - (head)->prev = (del)->prev; \ - } \ - } \ -} while (0) - -#define DL_COUNT(head,el,counter) \ - DL_COUNT2(head,el,counter,next) \ - -#define DL_COUNT2(head,el,counter,next) \ -do { \ - (counter) = 0; \ - DL_FOREACH2(head,el,next) { ++(counter); } \ -} while (0) - -#define DL_FOREACH(head,el) \ - DL_FOREACH2(head,el,next) - -#define DL_FOREACH2(head,el,next) \ - for ((el) = (head); el; (el) = (el)->next) - -/* this version is safe for deleting the elements during iteration */ -#define DL_FOREACH_SAFE(head,el,tmp) \ - DL_FOREACH_SAFE2(head,el,tmp,next) - -#define DL_FOREACH_SAFE2(head,el,tmp,next) \ - for ((el) = (head); (el) && ((tmp) = (el)->next, 1); (el) = (tmp)) - -/* these are identical to their singly-linked list counterparts */ -#define DL_SEARCH_SCALAR LL_SEARCH_SCALAR -#define DL_SEARCH LL_SEARCH -#define DL_SEARCH_SCALAR2 LL_SEARCH_SCALAR2 -#define DL_SEARCH2 LL_SEARCH2 - -#define DL_REPLACE_ELEM2(head, el, add, prev, next) \ -do { \ - assert((head) != NULL); \ - assert((el) != NULL); \ - assert((add) != NULL); \ - if ((head) == (el)) { \ - (head) = (add); \ - (add)->next = (el)->next; \ - if ((el)->next == NULL) { \ - (add)->prev = (add); \ - } else { \ - (add)->prev = (el)->prev; \ - (add)->next->prev = (add); \ - } \ - } else { \ - (add)->next = (el)->next; \ - (add)->prev = (el)->prev; \ - (add)->prev->next = (add); \ - if ((el)->next == NULL) { \ - (head)->prev = (add); \ - } else { \ - (add)->next->prev = (add); \ - } \ - } \ -} while (0) - -#define DL_REPLACE_ELEM(head, el, add) \ - DL_REPLACE_ELEM2(head, el, add, prev, next) - -#define DL_PREPEND_ELEM2(head, el, add, prev, next) \ -do { \ - if (el) { \ - assert((head) != NULL); \ - assert((add) != NULL); \ - (add)->next = (el); \ - (add)->prev = (el)->prev; \ - (el)->prev = (add); \ - if ((head) == (el)) { \ - (head) = (add); \ - } else { \ - (add)->prev->next = (add); \ - } \ - } else { \ - DL_APPEND2(head, add, prev, next); \ - } \ -} while (0) \ - -#define DL_PREPEND_ELEM(head, el, add) \ - DL_PREPEND_ELEM2(head, el, add, prev, next) - -#define DL_APPEND_ELEM2(head, el, add, prev, next) \ -do { \ - if (el) { \ - assert((head) != NULL); \ - assert((add) != NULL); \ - (add)->next = (el)->next; \ - (add)->prev = (el); \ - (el)->next = (add); \ - if ((add)->next) { \ - (add)->next->prev = (add); \ - } else { \ - (head)->prev = (add); \ - } \ - } else { \ - DL_PREPEND2(head, add, prev, next); \ - } \ -} while (0) \ - -#define DL_APPEND_ELEM(head, el, add) \ - DL_APPEND_ELEM2(head, el, add, prev, next) - -#ifdef NO_DECLTYPE -/* Here are VS2008 / NO_DECLTYPE replacements for a few functions */ - -#undef DL_INSERT_INORDER2 -#define DL_INSERT_INORDER2(head,add,cmp,prev,next) \ -do { \ - if ((head) == NULL) { \ - (add)->prev = (add); \ - (add)->next = NULL; \ - (head) = (add); \ - } else if ((cmp(head, add)) >= 0) { \ - (add)->prev = (head)->prev; \ - (add)->next = (head); \ - (head)->prev = (add); \ - (head) = (add); \ - } else { \ - char *_tmp = (char*)(head); \ - while ((head)->next && (cmp((head)->next, add)) < 0) { \ - (head) = (head)->next; \ - } \ - (add)->prev = (head); \ - (add)->next = (head)->next; \ - (head)->next = (add); \ - UTLIST_RS(head); \ - if ((add)->next) { \ - (add)->next->prev = (add); \ - } else { \ - (head)->prev = (add); \ - } \ - } \ -} while (0) -#endif /* NO_DECLTYPE */ - -/****************************************************************************** - * circular doubly linked list macros * - *****************************************************************************/ -#define CDL_APPEND(head,add) \ - CDL_APPEND2(head,add,prev,next) - -#define CDL_APPEND2(head,add,prev,next) \ -do { \ - if (head) { \ - (add)->prev = (head)->prev; \ - (add)->next = (head); \ - (head)->prev = (add); \ - (add)->prev->next = (add); \ - } else { \ - (add)->prev = (add); \ - (add)->next = (add); \ - (head) = (add); \ - } \ -} while (0) - -#define CDL_PREPEND(head,add) \ - CDL_PREPEND2(head,add,prev,next) - -#define CDL_PREPEND2(head,add,prev,next) \ -do { \ - if (head) { \ - (add)->prev = (head)->prev; \ - (add)->next = (head); \ - (head)->prev = (add); \ - (add)->prev->next = (add); \ - } else { \ - (add)->prev = (add); \ - (add)->next = (add); \ - } \ - (head) = (add); \ -} while (0) - -#define CDL_INSERT_INORDER(head,add,cmp) \ - CDL_INSERT_INORDER2(head,add,cmp,prev,next) - -#define CDL_INSERT_INORDER2(head,add,cmp,prev,next) \ -do { \ - LDECLTYPE(head) _tmp; \ - if (head) { \ - CDL_LOWER_BOUND2(head, _tmp, add, cmp, next); \ - CDL_APPEND_ELEM2(head, _tmp, add, prev, next); \ - } else { \ - (head) = (add); \ - (head)->next = (head); \ - (head)->prev = (head); \ - } \ -} while (0) - -#define CDL_LOWER_BOUND(head,elt,like,cmp) \ - CDL_LOWER_BOUND2(head,elt,like,cmp,next) - -#define CDL_LOWER_BOUND2(head,elt,like,cmp,next) \ -do { \ - if ((head) == NULL || (cmp(head, like)) >= 0) { \ - (elt) = NULL; \ - } else { \ - for ((elt) = (head); (elt)->next != (head); (elt) = (elt)->next) { \ - if ((cmp((elt)->next, like)) >= 0) { \ - break; \ - } \ - } \ - } \ -} while (0) - -#define CDL_DELETE(head,del) \ - CDL_DELETE2(head,del,prev,next) - -#define CDL_DELETE2(head,del,prev,next) \ -do { \ - if (((head)==(del)) && ((head)->next == (head))) { \ - (head) = NULL; \ - } else { \ - (del)->next->prev = (del)->prev; \ - (del)->prev->next = (del)->next; \ - if ((del) == (head)) (head)=(del)->next; \ - } \ -} while (0) - -#define CDL_COUNT(head,el,counter) \ - CDL_COUNT2(head,el,counter,next) \ - -#define CDL_COUNT2(head, el, counter,next) \ -do { \ - (counter) = 0; \ - CDL_FOREACH2(head,el,next) { ++(counter); } \ -} while (0) - -#define CDL_FOREACH(head,el) \ - CDL_FOREACH2(head,el,next) - -#define CDL_FOREACH2(head,el,next) \ - for ((el)=(head);el;(el)=(((el)->next==(head)) ? NULL : (el)->next)) - -#define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \ - CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) - -#define CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) \ - for ((el) = (head), (tmp1) = (head) ? (head)->prev : NULL; \ - (el) && ((tmp2) = (el)->next, 1); \ - (el) = ((el) == (tmp1) ? NULL : (tmp2))) - -#define CDL_SEARCH_SCALAR(head,out,field,val) \ - CDL_SEARCH_SCALAR2(head,out,field,val,next) - -#define CDL_SEARCH_SCALAR2(head,out,field,val,next) \ -do { \ - CDL_FOREACH2(head,out,next) { \ - if ((out)->field == (val)) break; \ - } \ -} while (0) - -#define CDL_SEARCH(head,out,elt,cmp) \ - CDL_SEARCH2(head,out,elt,cmp,next) - -#define CDL_SEARCH2(head,out,elt,cmp,next) \ -do { \ - CDL_FOREACH2(head,out,next) { \ - if ((cmp(out,elt))==0) break; \ - } \ -} while (0) - -#define CDL_REPLACE_ELEM2(head, el, add, prev, next) \ -do { \ - assert((head) != NULL); \ - assert((el) != NULL); \ - assert((add) != NULL); \ - if ((el)->next == (el)) { \ - (add)->next = (add); \ - (add)->prev = (add); \ - (head) = (add); \ - } else { \ - (add)->next = (el)->next; \ - (add)->prev = (el)->prev; \ - (add)->next->prev = (add); \ - (add)->prev->next = (add); \ - if ((head) == (el)) { \ - (head) = (add); \ - } \ - } \ -} while (0) - -#define CDL_REPLACE_ELEM(head, el, add) \ - CDL_REPLACE_ELEM2(head, el, add, prev, next) - -#define CDL_PREPEND_ELEM2(head, el, add, prev, next) \ -do { \ - if (el) { \ - assert((head) != NULL); \ - assert((add) != NULL); \ - (add)->next = (el); \ - (add)->prev = (el)->prev; \ - (el)->prev = (add); \ - (add)->prev->next = (add); \ - if ((head) == (el)) { \ - (head) = (add); \ - } \ - } else { \ - CDL_APPEND2(head, add, prev, next); \ - } \ -} while (0) - -#define CDL_PREPEND_ELEM(head, el, add) \ - CDL_PREPEND_ELEM2(head, el, add, prev, next) - -#define CDL_APPEND_ELEM2(head, el, add, prev, next) \ -do { \ - if (el) { \ - assert((head) != NULL); \ - assert((add) != NULL); \ - (add)->next = (el)->next; \ - (add)->prev = (el); \ - (el)->next = (add); \ - (add)->next->prev = (add); \ - } else { \ - CDL_PREPEND2(head, add, prev, next); \ - } \ -} while (0) - -#define CDL_APPEND_ELEM(head, el, add) \ - CDL_APPEND_ELEM2(head, el, add, prev, next) - -#ifdef NO_DECLTYPE -/* Here are VS2008 / NO_DECLTYPE replacements for a few functions */ - -#undef CDL_INSERT_INORDER2 -#define CDL_INSERT_INORDER2(head,add,cmp,prev,next) \ -do { \ - if ((head) == NULL) { \ - (add)->prev = (add); \ - (add)->next = (add); \ - (head) = (add); \ - } else if ((cmp(head, add)) >= 0) { \ - (add)->prev = (head)->prev; \ - (add)->next = (head); \ - (add)->prev->next = (add); \ - (head)->prev = (add); \ - (head) = (add); \ - } else { \ - char *_tmp = (char*)(head); \ - while ((char*)(head)->next != _tmp && (cmp((head)->next, add)) < 0) { \ - (head) = (head)->next; \ - } \ - (add)->prev = (head); \ - (add)->next = (head)->next; \ - (add)->next->prev = (add); \ - (head)->next = (add); \ - UTLIST_RS(head); \ - } \ -} while (0) -#endif /* NO_DECLTYPE */ - -#endif /* UTLIST_H */ diff --git a/test/http_decoder/uthash-2.3.0/include/utringbuffer.h b/test/http_decoder/uthash-2.3.0/include/utringbuffer.h deleted file mode 100644 index cf48131..0000000 --- a/test/http_decoder/uthash-2.3.0/include/utringbuffer.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -Copyright (c) 2015-2021, Troy D. Hanson http://troydhanson.github.com/uthash/ -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* a ring-buffer implementation using macros - */ -#ifndef UTRINGBUFFER_H -#define UTRINGBUFFER_H - -#define UTRINGBUFFER_VERSION 2.3.0 - -#include -#include -#include "utarray.h" // for "UT_icd" - -typedef struct { - unsigned i; /* index of next available slot; wraps at n */ - unsigned n; /* capacity */ - unsigned char f; /* full */ - UT_icd icd; /* initializer, copy and destructor functions */ - char *d; /* n slots of size icd->sz */ -} UT_ringbuffer; - -#define utringbuffer_init(a, _n, _icd) do { \ - memset(a, 0, sizeof(UT_ringbuffer)); \ - (a)->icd = *(_icd); \ - (a)->n = (_n); \ - if ((a)->n) { (a)->d = (char*)malloc((a)->n * (_icd)->sz); } \ -} while(0) - -#define utringbuffer_clear(a) do { \ - if ((a)->icd.dtor) { \ - if ((a)->f) { \ - unsigned _ut_i; \ - for (_ut_i = 0; _ut_i < (a)->n; ++_ut_i) { \ - (a)->icd.dtor(utringbuffer_eltptr(a, _ut_i)); \ - } \ - } else { \ - unsigned _ut_i; \ - for (_ut_i = 0; _ut_i < (a)->i; ++_ut_i) { \ - (a)->icd.dtor(utringbuffer_eltptr(a, _ut_i)); \ - } \ - } \ - } \ - (a)->i = 0; \ - (a)->f = 0; \ -} while(0) - -#define utringbuffer_done(a) do { \ - utringbuffer_clear(a); \ - free((a)->d); (a)->d = NULL; \ - (a)->n = 0; \ -} while(0) - -#define utringbuffer_new(a,n,_icd) do { \ - a = (UT_ringbuffer*)malloc(sizeof(UT_ringbuffer)); \ - utringbuffer_init(a, n, _icd); \ -} while(0) - -#define utringbuffer_free(a) do { \ - utringbuffer_done(a); \ - free(a); \ -} while(0) - -#define utringbuffer_push_back(a,p) do { \ - if ((a)->icd.dtor && (a)->f) { (a)->icd.dtor(_utringbuffer_internalptr(a,(a)->i)); } \ - if ((a)->icd.copy) { (a)->icd.copy( _utringbuffer_internalptr(a,(a)->i), p); } \ - else { memcpy(_utringbuffer_internalptr(a,(a)->i), p, (a)->icd.sz); }; \ - if (++(a)->i == (a)->n) { (a)->i = 0; (a)->f = 1; } \ -} while(0) - -#define utringbuffer_len(a) ((a)->f ? (a)->n : (a)->i) -#define utringbuffer_empty(a) ((a)->i == 0 && !(a)->f) -#define utringbuffer_full(a) ((a)->f != 0) - -#define _utringbuffer_real_idx(a,j) ((a)->f ? ((j) + (a)->i) % (a)->n : (j)) -#define _utringbuffer_internalptr(a,j) ((void*)((a)->d + ((a)->icd.sz * (j)))) -#define utringbuffer_eltptr(a,j) ((0 <= (j) && (j) < utringbuffer_len(a)) ? _utringbuffer_internalptr(a,_utringbuffer_real_idx(a,j)) : NULL) - -#define _utringbuffer_fake_idx(a,j) ((a)->f ? ((j) + (a)->n - (a)->i) % (a)->n : (j)) -#define _utringbuffer_internalidx(a,e) (((char*)(e) >= (a)->d) ? (((char*)(e) - (a)->d)/(a)->icd.sz) : -1) -#define utringbuffer_eltidx(a,e) _utringbuffer_fake_idx(a, _utringbuffer_internalidx(a,e)) - -#define utringbuffer_front(a) utringbuffer_eltptr(a,0) -#define utringbuffer_next(a,e) ((e)==NULL ? utringbuffer_front(a) : utringbuffer_eltptr(a, utringbuffer_eltidx(a,e)+1)) -#define utringbuffer_prev(a,e) ((e)==NULL ? utringbuffer_back(a) : utringbuffer_eltptr(a, utringbuffer_eltidx(a,e)-1)) -#define utringbuffer_back(a) (utringbuffer_empty(a) ? NULL : utringbuffer_eltptr(a, utringbuffer_len(a) - 1)) - -#endif /* UTRINGBUFFER_H */ diff --git a/test/http_decoder/uthash-2.3.0/include/utstack.h b/test/http_decoder/uthash-2.3.0/include/utstack.h deleted file mode 100644 index 2dbfec8..0000000 --- a/test/http_decoder/uthash-2.3.0/include/utstack.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright (c) 2018-2021, Troy D. Hanson http://troydhanson.github.com/uthash/ -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef UTSTACK_H -#define UTSTACK_H - -#define UTSTACK_VERSION 2.3.0 - -/* - * This file contains macros to manipulate a singly-linked list as a stack. - * - * To use utstack, your structure must have a "next" pointer. - * - * ----------------.EXAMPLE ------------------------- - * struct item { - * int id; - * struct item *next; - * } - * - * struct item *stack = NULL: - * - * int main() { - * int count; - * struct item *tmp; - * struct item *item = malloc(sizeof *item); - * item->id = 42; - * STACK_COUNT(stack, tmp, count); assert(count == 0); - * STACK_PUSH(stack, item); - * STACK_COUNT(stack, tmp, count); assert(count == 1); - * STACK_POP(stack, item); - * free(item); - * STACK_COUNT(stack, tmp, count); assert(count == 0); - * } - * -------------------------------------------------- - */ - -#define STACK_TOP(head) (head) - -#define STACK_EMPTY(head) (!(head)) - -#define STACK_PUSH(head,add) \ - STACK_PUSH2(head,add,next) - -#define STACK_PUSH2(head,add,next) \ -do { \ - (add)->next = (head); \ - (head) = (add); \ -} while (0) - -#define STACK_POP(head,result) \ - STACK_POP2(head,result,next) - -#define STACK_POP2(head,result,next) \ -do { \ - (result) = (head); \ - (head) = (head)->next; \ -} while (0) - -#define STACK_COUNT(head,el,counter) \ - STACK_COUNT2(head,el,counter,next) \ - -#define STACK_COUNT2(head,el,counter,next) \ -do { \ - (counter) = 0; \ - for ((el) = (head); el; (el) = (el)->next) { ++(counter); } \ -} while (0) - -#endif /* UTSTACK_H */ diff --git a/test/http_decoder/uthash-2.3.0/include/utstring.h b/test/http_decoder/uthash-2.3.0/include/utstring.h deleted file mode 100644 index 009b4c8..0000000 --- a/test/http_decoder/uthash-2.3.0/include/utstring.h +++ /dev/null @@ -1,407 +0,0 @@ -/* -Copyright (c) 2008-2021, Troy D. Hanson http://troydhanson.github.com/uthash/ -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* a dynamic string implementation using macros - */ -#ifndef UTSTRING_H -#define UTSTRING_H - -#define UTSTRING_VERSION 2.3.0 - -#include -#include -#include -#include - -#ifdef __GNUC__ -#define UTSTRING_UNUSED __attribute__((__unused__)) -#else -#define UTSTRING_UNUSED -#endif - -#ifdef oom -#error "The name of macro 'oom' has been changed to 'utstring_oom'. Please update your code." -#define utstring_oom() oom() -#endif - -#ifndef utstring_oom -#define utstring_oom() exit(-1) -#endif - -typedef struct { - char *d; /* pointer to allocated buffer */ - size_t n; /* allocated capacity */ - size_t i; /* index of first unused byte */ -} UT_string; - -#define utstring_reserve(s,amt) \ -do { \ - if (((s)->n - (s)->i) < (size_t)(amt)) { \ - char *utstring_tmp = (char*)realloc( \ - (s)->d, (s)->n + (amt)); \ - if (!utstring_tmp) { \ - utstring_oom(); \ - } \ - (s)->d = utstring_tmp; \ - (s)->n += (amt); \ - } \ -} while(0) - -#define utstring_init(s) \ -do { \ - (s)->n = 0; (s)->i = 0; (s)->d = NULL; \ - utstring_reserve(s,100); \ - (s)->d[0] = '\0'; \ -} while(0) - -#define utstring_done(s) \ -do { \ - if ((s)->d != NULL) free((s)->d); \ - (s)->n = 0; \ -} while(0) - -#define utstring_free(s) \ -do { \ - utstring_done(s); \ - free(s); \ -} while(0) - -#define utstring_new(s) \ -do { \ - (s) = (UT_string*)malloc(sizeof(UT_string)); \ - if (!(s)) { \ - utstring_oom(); \ - } \ - utstring_init(s); \ -} while(0) - -#define utstring_renew(s) \ -do { \ - if (s) { \ - utstring_clear(s); \ - } else { \ - utstring_new(s); \ - } \ -} while(0) - -#define utstring_clear(s) \ -do { \ - (s)->i = 0; \ - (s)->d[0] = '\0'; \ -} while(0) - -#define utstring_bincpy(s,b,l) \ -do { \ - utstring_reserve((s),(l)+1); \ - if (l) memcpy(&(s)->d[(s)->i], b, l); \ - (s)->i += (l); \ - (s)->d[(s)->i]='\0'; \ -} while(0) - -#define utstring_concat(dst,src) \ -do { \ - utstring_reserve((dst),((src)->i)+1); \ - if ((src)->i) memcpy(&(dst)->d[(dst)->i], (src)->d, (src)->i); \ - (dst)->i += (src)->i; \ - (dst)->d[(dst)->i]='\0'; \ -} while(0) - -#define utstring_len(s) ((s)->i) - -#define utstring_body(s) ((s)->d) - -UTSTRING_UNUSED static void utstring_printf_va(UT_string *s, const char *fmt, va_list ap) { - int n; - va_list cp; - for (;;) { -#ifdef _WIN32 - cp = ap; -#else - va_copy(cp, ap); -#endif - n = vsnprintf (&s->d[s->i], s->n-s->i, fmt, cp); - va_end(cp); - - if ((n > -1) && ((size_t) n < (s->n-s->i))) { - s->i += n; - return; - } - - /* Else try again with more space. */ - if (n > -1) utstring_reserve(s,n+1); /* exact */ - else utstring_reserve(s,(s->n)*2); /* 2x */ - } -} -#ifdef __GNUC__ -/* support printf format checking (2=the format string, 3=start of varargs) */ -static void utstring_printf(UT_string *s, const char *fmt, ...) - __attribute__ (( format( printf, 2, 3) )); -#endif -UTSTRING_UNUSED static void utstring_printf(UT_string *s, const char *fmt, ...) { - va_list ap; - va_start(ap,fmt); - utstring_printf_va(s,fmt,ap); - va_end(ap); -} - -/******************************************************************************* - * begin substring search functions * - ******************************************************************************/ -/* Build KMP table from left to right. */ -UTSTRING_UNUSED static void _utstring_BuildTable( - const char *P_Needle, - size_t P_NeedleLen, - long *P_KMP_Table) -{ - long i, j; - - i = 0; - j = i - 1; - P_KMP_Table[i] = j; - while (i < (long) P_NeedleLen) - { - while ( (j > -1) && (P_Needle[i] != P_Needle[j]) ) - { - j = P_KMP_Table[j]; - } - i++; - j++; - if (i < (long) P_NeedleLen) - { - if (P_Needle[i] == P_Needle[j]) - { - P_KMP_Table[i] = P_KMP_Table[j]; - } - else - { - P_KMP_Table[i] = j; - } - } - else - { - P_KMP_Table[i] = j; - } - } - - return; -} - - -/* Build KMP table from right to left. */ -UTSTRING_UNUSED static void _utstring_BuildTableR( - const char *P_Needle, - size_t P_NeedleLen, - long *P_KMP_Table) -{ - long i, j; - - i = P_NeedleLen - 1; - j = i + 1; - P_KMP_Table[i + 1] = j; - while (i >= 0) - { - while ( (j < (long) P_NeedleLen) && (P_Needle[i] != P_Needle[j]) ) - { - j = P_KMP_Table[j + 1]; - } - i--; - j--; - if (i >= 0) - { - if (P_Needle[i] == P_Needle[j]) - { - P_KMP_Table[i + 1] = P_KMP_Table[j + 1]; - } - else - { - P_KMP_Table[i + 1] = j; - } - } - else - { - P_KMP_Table[i + 1] = j; - } - } - - return; -} - - -/* Search data from left to right. ( Multiple search mode. ) */ -UTSTRING_UNUSED static long _utstring_find( - const char *P_Haystack, - size_t P_HaystackLen, - const char *P_Needle, - size_t P_NeedleLen, - long *P_KMP_Table) -{ - long i, j; - long V_FindPosition = -1; - - /* Search from left to right. */ - i = j = 0; - while ( (j < (int)P_HaystackLen) && (((P_HaystackLen - j) + i) >= P_NeedleLen) ) - { - while ( (i > -1) && (P_Needle[i] != P_Haystack[j]) ) - { - i = P_KMP_Table[i]; - } - i++; - j++; - if (i >= (int)P_NeedleLen) - { - /* Found. */ - V_FindPosition = j - i; - break; - } - } - - return V_FindPosition; -} - - -/* Search data from right to left. ( Multiple search mode. ) */ -UTSTRING_UNUSED static long _utstring_findR( - const char *P_Haystack, - size_t P_HaystackLen, - const char *P_Needle, - size_t P_NeedleLen, - long *P_KMP_Table) -{ - long i, j; - long V_FindPosition = -1; - - /* Search from right to left. */ - j = (P_HaystackLen - 1); - i = (P_NeedleLen - 1); - while ( (j >= 0) && (j >= i) ) - { - while ( (i < (int)P_NeedleLen) && (P_Needle[i] != P_Haystack[j]) ) - { - i = P_KMP_Table[i + 1]; - } - i--; - j--; - if (i < 0) - { - /* Found. */ - V_FindPosition = j + 1; - break; - } - } - - return V_FindPosition; -} - - -/* Search data from left to right. ( One time search mode. ) */ -UTSTRING_UNUSED static long utstring_find( - UT_string *s, - long P_StartPosition, /* Start from 0. -1 means last position. */ - const char *P_Needle, - size_t P_NeedleLen) -{ - long V_StartPosition; - long V_HaystackLen; - long *V_KMP_Table; - long V_FindPosition = -1; - - if (P_StartPosition < 0) - { - V_StartPosition = s->i + P_StartPosition; - } - else - { - V_StartPosition = P_StartPosition; - } - V_HaystackLen = s->i - V_StartPosition; - if ( (V_HaystackLen >= (long) P_NeedleLen) && (P_NeedleLen > 0) ) - { - V_KMP_Table = (long *)malloc(sizeof(long) * (P_NeedleLen + 1)); - if (V_KMP_Table != NULL) - { - _utstring_BuildTable(P_Needle, P_NeedleLen, V_KMP_Table); - - V_FindPosition = _utstring_find(s->d + V_StartPosition, - V_HaystackLen, - P_Needle, - P_NeedleLen, - V_KMP_Table); - if (V_FindPosition >= 0) - { - V_FindPosition += V_StartPosition; - } - - free(V_KMP_Table); - } - } - - return V_FindPosition; -} - - -/* Search data from right to left. ( One time search mode. ) */ -UTSTRING_UNUSED static long utstring_findR( - UT_string *s, - long P_StartPosition, /* Start from 0. -1 means last position. */ - const char *P_Needle, - size_t P_NeedleLen) -{ - long V_StartPosition; - long V_HaystackLen; - long *V_KMP_Table; - long V_FindPosition = -1; - - if (P_StartPosition < 0) - { - V_StartPosition = s->i + P_StartPosition; - } - else - { - V_StartPosition = P_StartPosition; - } - V_HaystackLen = V_StartPosition + 1; - if ( (V_HaystackLen >= (long) P_NeedleLen) && (P_NeedleLen > 0) ) - { - V_KMP_Table = (long *)malloc(sizeof(long) * (P_NeedleLen + 1)); - if (V_KMP_Table != NULL) - { - _utstring_BuildTableR(P_Needle, P_NeedleLen, V_KMP_Table); - - V_FindPosition = _utstring_findR(s->d, - V_HaystackLen, - P_Needle, - P_NeedleLen, - V_KMP_Table); - - free(V_KMP_Table); - } - } - - return V_FindPosition; -} -/******************************************************************************* - * end substring search functions * - ******************************************************************************/ - -#endif /* UTSTRING_H */ diff --git a/vendor/CMakeLists.txt b/vendor/CMakeLists.txt index 03736be..f68d69f 100644 --- a/vendor/CMakeLists.txt +++ b/vendor/CMakeLists.txt @@ -46,30 +46,30 @@ set_property(TARGET cjson-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTAL ExternalProject_Add(llhttp PREFIX llhttp URL ${CMAKE_CURRENT_SOURCE_DIR}/llhttp-release-v9.2.1.tar.gz URL_MD5 355ecc90e622035e3e1693a96a0c233b - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${VENDOR_BUILD} -DBUILD_STATIC_LIBS=ON -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_C_FLAGS="-fPIC") - -file(MAKE_DIRECTORY ${VENDOR_BUILD}/include) + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= -DBUILD_STATIC_LIBS=ON -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_C_FLAGS="-fPIC") +ExternalProject_Get_Property(llhttp INSTALL_DIR) +file(MAKE_DIRECTORY ${INSTALL_DIR}/include) add_library(llhttp-static STATIC IMPORTED GLOBAL) add_dependencies(llhttp-static llhttp) -set_property(TARGET llhttp-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${VENDOR_BUILD}/include) -set_property(TARGET llhttp-static PROPERTY IMPORTED_LOCATION ${VENDOR_BUILD}/lib64/libllhttp.a) +set_property(TARGET llhttp-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) +set_property(TARGET llhttp-static PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib64/libllhttp.a) #brotli-v1.0.9 -ExternalProject_Add(libbrotli PREFIX libbrotli +ExternalProject_Add(brotli PREFIX brotli URL ${CMAKE_CURRENT_SOURCE_DIR}/brotli-v1.0.9.tar.gz URL_MD5 c2274f0c7af8470ad514637c35bcee7d - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${VENDOR_BUILD} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}) - -file(MAKE_DIRECTORY ${VENDOR_BUILD}/include) + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}) +ExternalProject_Get_Property(brotli INSTALL_DIR) +file(MAKE_DIRECTORY ${INSTALL_DIR}/include) add_library(brotli-common-static STATIC IMPORTED GLOBAL) -add_dependencies(brotli-common-static libbrotli) -set_property(TARGET brotli-common-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${VENDOR_BUILD}/include) -set_property(TARGET brotli-common-static PROPERTY IMPORTED_LOCATION ${VENDOR_BUILD}/lib64/libbrotlicommon-static.a) +add_dependencies(brotli-common-static brotli) +set_property(TARGET brotli-common-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) +set_property(TARGET brotli-common-static PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib64/libbrotlicommon-static.a) add_library(brotli-dec-static STATIC IMPORTED GLOBAL) -add_dependencies(brotli-dec-static libbrotli) -set_property(TARGET brotli-dec-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${VENDOR_BUILD}/include) -set_property(TARGET brotli-dec-static PROPERTY IMPORTED_LOCATION ${VENDOR_BUILD}/lib64/libbrotlidec-static.a) \ No newline at end of file +add_dependencies(brotli-dec-static brotli) +set_property(TARGET brotli-dec-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) +set_property(TARGET brotli-dec-static PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib64/libbrotlidec-static.a)