From c7b97c072b52676b6c17bf6713f399ce0273b308 Mon Sep 17 00:00:00 2001 From: lijia Date: Tue, 19 Nov 2024 19:17:00 +0800 Subject: TSG-23819: support access latency, internet latency and srtt --- .../for_gtest_only/tcp/tcp_http_rtt.pcap | Bin 0 -> 3505 bytes .../for_gtest_only/tcp/tcp_rtt_long_duration.pcap | Bin 0 -> 448772 bytes include/private/stream_internal.h | 20 +- include/public/stream_inc/stream_control.h | 126 +++++------ module_test/src/gtest_main.cpp | 24 +-- module_test/src/gtest_sapp_fun.h | 8 +- module_test/src/gtest_sapp_support.cpp | 29 ++- module_test/src/gtest_sapp_support_plug.cpp | 146 ++++++++++--- src/dealpkt/deal_tcp.c | 233 +++++++++++++++++---- src/dealpkt/plug_support.c | 47 ++++- test/test_app_sapp.c | 55 +++-- 11 files changed, 497 insertions(+), 191 deletions(-) create mode 100644 benchmark_pcap/for_gtest_only/tcp/tcp_http_rtt.pcap create mode 100644 benchmark_pcap/for_gtest_only/tcp/tcp_rtt_long_duration.pcap diff --git a/benchmark_pcap/for_gtest_only/tcp/tcp_http_rtt.pcap b/benchmark_pcap/for_gtest_only/tcp/tcp_http_rtt.pcap new file mode 100644 index 0000000..ff661e3 Binary files /dev/null and b/benchmark_pcap/for_gtest_only/tcp/tcp_http_rtt.pcap differ diff --git a/benchmark_pcap/for_gtest_only/tcp/tcp_rtt_long_duration.pcap b/benchmark_pcap/for_gtest_only/tcp/tcp_rtt_long_duration.pcap new file mode 100644 index 0000000..521a49e Binary files /dev/null and b/benchmark_pcap/for_gtest_only/tcp/tcp_rtt_long_duration.pcap differ diff --git a/include/private/stream_internal.h b/include/private/stream_internal.h index 044bc32..731c81f 100644 --- a/include/private/stream_internal.h +++ b/include/private/stream_internal.h @@ -6,6 +6,7 @@ #include "mesa_pkt_dump.h" #include "sapp_limits.h" #include "stream.h" +#include //#define STREAM_BASE_MD5_CHECK "dd09b3b11993cc835200db477dad7d4b" //#define STREAM_CONTROL_MD5_CHECK "75aab0821e489b84355fa22ad02a2e78" @@ -57,6 +58,8 @@ #ifndef uuid_t typedef unsigned char uuid_t[16]; #endif +#define TCP_SAMPLING_SRTT_INTERVAL_MS (5000) /* millisecond */ +#define TCP_SRTT_EWMA_ALPHA (0.125) #ifdef __cplusplus extern "C" { @@ -264,6 +267,18 @@ struct streaminfo_private uuid_t stream_uuid; }; +#define DOUBLE_EPSILON 1e-15 +#define DOUBLE_IS_ZERO(v) (fabs(v) < DOUBLE_EPSILON) +struct tcp_srtt_metric +{ + long long last_rtt_sampling_time; + unsigned short half_pkt_interval_c2s; + unsigned short half_pkt_interval_s2c; + unsigned short rtt_dpi_server_dpi; /* millisecond, duration of 'dpi-->server-->dpi', every Nsec throughout the life of stream */ + unsigned short rtt_dpi_client_dpi; /* millisecond, duration of 'dpi-->client-->dpi', every Nsec throughout the life of stream */ + double srtt; /* Smoothed Round-Trip Time, update every Nsec throughout the life of stream */ +}; + struct tcpdetail_private { /* ����ṹ�����ڽṹ����?, ָ���ַ���Ի���ǿ? */ @@ -304,10 +319,11 @@ struct tcpdetail_private void *pAllpktpme; //��״̬��tcp���������� struct tcp_flow_stat *flow_stat; /* 2016-07-14 lijia add, ���ڼ�¼TCP��data���ļ���, ʵ���ڴ������ͷ���projectģ����?, ����ΪNULL, */ struct tcp_flow_stat *deduce_flow_stat; /* 2018-10-30 lijia add, ���ڼ�¼������ƶϳ������ϴ��������, ���������ij���; �Լ�����������?, �Զ�Ӧ���յ������� */ - unsigned short rtt_csc; - unsigned short rtt_scs; + double internet_latency; /* millisecond, from the hashshake phase */ + double access_latency; /* millisecond, from the hashshake phase */ long long last_c2s_pkt_rcv_time; long long last_s2c_pkt_rcv_time; + struct tcp_srtt_metric srtt_metric; }; struct udpdetail_private diff --git a/include/public/stream_inc/stream_control.h b/include/public/stream_inc/stream_control.h index 4353f70..eb3e0bd 100644 --- a/include/public/stream_inc/stream_control.h +++ b/include/public/stream_inc/stream_control.h @@ -14,68 +14,70 @@ extern "C" /* option of stream, - MSO_IGNORE_RST_FIN: will not be terminated by RST, FIN packet, only if timeout or in LRU tail, it will be eliminated. - */ - enum MESA_stream_opt - { - __MSO_PAD = 0, /* placeholder */ - MSO_MAX_UNORDER = 1, /* opt_val type must be struct max_unorder_opt */ - MSO_NEED_ACK, /* opt_val type must be unsigned char, value only be [0,1] */ - MSO_TAKEOVER, /* opt_val type must be int, value only be [0,1] */ - MSO_TIMEOUT, /* opt_val type must be unsigned short */ - MSO_IGNORE_RST_FIN, /* opt_val type must be unsigned char, value only be [0,1] */ - MSO_TCP_CREATE_LINK_MODE, /* opt_val must be unsigned char, refer to TCP_CTEAT_LINK_xxx */ - MSO_TCP_ISN_C2S, /* Host-order, opt_val type must be unsigned int */ - MSO_TCP_ISN_S2C, /* Host-order, opt_val type must be unsigned int */ - MSO_TCP_SYN_OPT, /* opt_val must be struct tcp_option **, opt_val_len [OUT} is struct tcp_option number, valid only if SYN packet is captured */ - MSO_TCP_SYNACK_OPT, /* opt_val must be struct tcp_option **, opt_val_len [OUT} is struct tcp_option number, valid only if SYN/ACK packet is captured */ - MSO_STREAM_TUNNEL_TYPE, /* opt_val must be unsigned short, refer to enum stream_carry_tunnel_t */ - MSO_STREAM_CLOSE_REASON, /* opt_val type must be unsigned char, refer to stream_close_reason_t */ - MSO_STREAM_VXLAN_INFO, /* opt_val type must be struct vxlan_info, only support for MAC-in-MAC encapsulation in mirror mode */ - MSO_TCPALL_VALID_AFTER_KILL, /* opt_val type must be unsigned char, value only be [0,1]; Warning, this option is obsolete, use MESA_rst_tcp() instead */ - MSO_GLOBAL_STREAM_ID, /* opt_val type must be unsigned long long, is value-result argument, IN: device_id, value range[0, 4095]; OUT:global stream id */ - MSO_DROP_STREAM, /* opt_val type must be int, value only be [0,1]; similar to DROPPKT, but effective scope is all subsequent packets of this stream. */ - MSO_TCP_RST_REMEDY, /* opt_val type must be int, value only be [0,1]; if not set this, default is disable. */ - MSO_TOTAL_INBOUND_PKT, /* inbound packet number of this stream, opt_val type must be unsigned long long */ - MSO_TOTAL_INBOUND_BYTE, /* inbound packet byte of this stream, opt_val type must be unsigned long long */ - MSO_TOTAL_OUTBOUND_PKT, /* outbound packet pkt of this stream, opt_val type must be unsigned long long */ - MSO_TOTAL_OUTBOUND_BYTE, /* outbound packet byte of this stream, opt_val type must be unsigned long long */ - MSO_STREAM_CREATE_TIMESTAMP_MS, /* first pkt arrive timestamp of this stream, opt_val type must be unsigned long long */ - MSO_TOTAL_INBOUND_BYTE_RAW, /* inbound packet byte of this stream, raw packet len, include ip hdr, ethernet hdr... opt_val type must be unsigned long long */ - MSO_TOTAL_OUTBOUND_BYTE_RAW, /* outbound packet byte of this stream, raw packet len, include ip hdr, ethernet hdr... opt_val type must be unsigned long long */ - MSO_STREAM_UP_LAYER_TUNNEL_TYPE, /* opt_val must be unsigned short, refer to enum stream_carry_tunnel_t */ - MSO_STREAM_PLUG_PME, /* opt_val type must be struct mso_plug_pme, this is a value-result argument, the caller should set plug_name and plug_entry_type, only support: TCP, TCP_ALL, UDP */ - MSO_DROP_CURRENT_PKT, /* opt_val type must be int, value only be [0,1], notice the difference between MSO_DROP_CURRENT_PKT and MSO_DROP_STREAM, MSO_DROP_CURRENT_PKT only discard current packet, but MSO_DROP_STREAM discard all subsequent packets of stream */ - MSO_HAVE_DUP_PKT, /* opt_val type must be int, value only be [0, 1, -2], if the current stream found duplicate packets ? 0:no; 1:yes; -2: not sure */ - MSO_STREAM_LASTUPDATE_TIMESTAMP_MS, /* latest pkt arrive timestamp of this stream, opt_val type must be unsigned long long */ - MSO_STREAM_TIMED, - MSO_STREAM_APPLEND_SEGMENT_ID_LIST, - MSO_STREAM_PREPLEND_SEGMENT_ID_LIST, - MSO_STREAM_SET_DATAMETA_TRACE_ID, - MSO_STREAM_C2S_RAWPKT_HDR, - MSO_STREAM_S2C_RAWPKT_HDR, - MSO_STREAM_C2S_SYN_NUM, - MSO_STREAM_S2C_SYN_NUM, - MSO_STREAM_INBOND_LINK_ID, - MSO_STREAM_OUTBOND_LINK_ID, - MSO_STREAM_C2S_ROUTE_DIRECTION, - MSO_STREAM_INBOND_ROUTE_CTX, - MSO_STREAM_OUTBOND_ROUTE_CTX, - MSO_STREAM_C2S_LINK_ID, - MSO_STREAM_S2C_LINK_ID, - MSO_STREAM_C2S_ROUTE_CTX, - MSO_STREAM_S2C_ROUTE_CTX, - MSO_IP_TTL_C2S, /* opt_val type must be unsigned char, IPv4 is TTL, IPv6 is Hop Limit */ - MSO_IP_TTL_S2C, /* opt_val type must be unsigned char, IPv4 is TTL, IPv6 is Hop Limit */ - MSO_TCP_RTT_CSC, /* opt_val type must be unsigned short, the full RTT is client->tsg->server->tsg->client, this is |tsg->server->tsg| */ - MSO_TCP_RTT_SCS, /* opt_val type must be unsigned short, the full RTT is server->tsg->client->tsg->server, this is |tsg->client->tsg| */ - MSO_STREAM_C2S_SEGMENT_ID_LIST, - MSO_STREAM_S2C_SEGMENT_ID_LIST, - MSO_STREAM_INBOND_SEGMENT_ID_LIST, - MSO_STREAM_OUTBOND_SEGMENT_ID_LIST, - MSO_STREAM_UUID, /* opt_val is uuid_t (unsigned char [16]) */ - __MSO_MAX, - }; + MSO_IGNORE_RST_FIN: will not be terminated by RST, FIN packet, only if timeout or in LRU tail, it will be eliminated. +*/ +enum MESA_stream_opt{ + __MSO_PAD = 0, /* placeholder */ + MSO_MAX_UNORDER = 1, /* opt_val type must be struct max_unorder_opt */ + MSO_NEED_ACK, /* opt_val type must be unsigned char, value only be [0,1] */ + MSO_TAKEOVER, /* opt_val type must be int, value only be [0,1] */ + MSO_TIMEOUT, /* opt_val type must be unsigned short */ + MSO_IGNORE_RST_FIN, /* opt_val type must be unsigned char, value only be [0,1] */ + MSO_TCP_CREATE_LINK_MODE, /* opt_val must be unsigned char, refer to TCP_CTEAT_LINK_xxx */ + MSO_TCP_ISN_C2S, /* Host-order, opt_val type must be unsigned int */ + MSO_TCP_ISN_S2C, /* Host-order, opt_val type must be unsigned int */ + MSO_TCP_SYN_OPT, /* opt_val must be struct tcp_option **, opt_val_len [OUT} is struct tcp_option number, valid only if SYN packet is captured */ + MSO_TCP_SYNACK_OPT, /* opt_val must be struct tcp_option **, opt_val_len [OUT} is struct tcp_option number, valid only if SYN/ACK packet is captured */ + MSO_STREAM_TUNNEL_TYPE, /* opt_val must be unsigned short, refer to enum stream_carry_tunnel_t */ + MSO_STREAM_CLOSE_REASON, /* opt_val type must be unsigned char, refer to stream_close_reason_t */ + MSO_STREAM_VXLAN_INFO, /* opt_val type must be struct vxlan_info, only support for MAC-in-MAC encapsulation in mirror mode */ + MSO_TCPALL_VALID_AFTER_KILL, /* opt_val type must be unsigned char, value only be [0,1]; Warning, this option is obsolete, use MESA_rst_tcp() instead */ + MSO_GLOBAL_STREAM_ID, /* opt_val type must be unsigned long long, is value-result argument, IN: device_id, value range[0, 4095]; OUT:global stream id */ + MSO_DROP_STREAM, /* opt_val type must be int, value only be [0,1]; similar to DROPPKT, but effective scope is all subsequent packets of this stream. */ + MSO_TCP_RST_REMEDY, /* opt_val type must be int, value only be [0,1]; if not set this, default is disable. */ + MSO_TOTAL_INBOUND_PKT, /* inbound packet number of this stream, opt_val type must be unsigned long long */ + MSO_TOTAL_INBOUND_BYTE, /* inbound packet byte of this stream, opt_val type must be unsigned long long */ + MSO_TOTAL_OUTBOUND_PKT, /* outbound packet pkt of this stream, opt_val type must be unsigned long long */ + MSO_TOTAL_OUTBOUND_BYTE,/* outbound packet byte of this stream, opt_val type must be unsigned long long */ + MSO_STREAM_CREATE_TIMESTAMP_MS,/* first pkt arrive timestamp of this stream, opt_val type must be unsigned long long */ + MSO_TOTAL_INBOUND_BYTE_RAW, /* inbound packet byte of this stream, raw packet len, include ip hdr, ethernet hdr... opt_val type must be unsigned long long */ + MSO_TOTAL_OUTBOUND_BYTE_RAW,/* outbound packet byte of this stream, raw packet len, include ip hdr, ethernet hdr... opt_val type must be unsigned long long */ + MSO_STREAM_UP_LAYER_TUNNEL_TYPE, /* opt_val must be unsigned short, refer to enum stream_carry_tunnel_t */ + MSO_STREAM_PLUG_PME, /* opt_val type must be struct mso_plug_pme, this is a value-result argument, the caller should set plug_name and plug_entry_type, only support: TCP, TCP_ALL, UDP */ + MSO_DROP_CURRENT_PKT, /* opt_val type must be int, value only be [0,1], notice the difference between MSO_DROP_CURRENT_PKT and MSO_DROP_STREAM, MSO_DROP_CURRENT_PKT only discard current packet, but MSO_DROP_STREAM discard all subsequent packets of stream */ + MSO_HAVE_DUP_PKT, /* opt_val type must be int, value only be [0, 1, -2], if the current stream found duplicate packets ? 0:no; 1:yes; -2: not sure */ + MSO_STREAM_LASTUPDATE_TIMESTAMP_MS,/* latest pkt arrive timestamp of this stream, opt_val type must be unsigned long long */ + MSO_STREAM_TIMED, + MSO_STREAM_APPLEND_SEGMENT_ID_LIST, + MSO_STREAM_PREPLEND_SEGMENT_ID_LIST, + MSO_STREAM_SET_DATAMETA_TRACE_ID, + MSO_STREAM_C2S_RAWPKT_HDR, + MSO_STREAM_S2C_RAWPKT_HDR, + MSO_STREAM_C2S_SYN_NUM, + MSO_STREAM_S2C_SYN_NUM, + MSO_STREAM_INBOND_LINK_ID, + MSO_STREAM_OUTBOND_LINK_ID, + MSO_STREAM_C2S_ROUTE_DIRECTION, + MSO_STREAM_INBOND_ROUTE_CTX, + MSO_STREAM_OUTBOND_ROUTE_CTX, + MSO_STREAM_C2S_LINK_ID, + MSO_STREAM_S2C_LINK_ID, + MSO_STREAM_C2S_ROUTE_CTX, + MSO_STREAM_S2C_ROUTE_CTX, + MSO_IP_TTL_C2S, /* opt_val type must be unsigned char, IPv4 is TTL, IPv6 is Hop Limit */ + MSO_IP_TTL_S2C, /* opt_val type must be unsigned char, IPv4 is TTL, IPv6 is Hop Limit */ + MSO_TCP_RTT_CSC, /* deprecated in v24.12 */ + MSO_TCP_RTT_SCS, /* deprecated in v24.12 */ + MSO_STREAM_C2S_SEGMENT_ID_LIST, + MSO_STREAM_S2C_SEGMENT_ID_LIST, + MSO_STREAM_INBOND_SEGMENT_ID_LIST, + MSO_STREAM_OUTBOND_SEGMENT_ID_LIST, + MSO_STREAM_UUID, /* opt_val is uuid_t (unsigned char [16]) */ + MSO_ACCESS_LATENCY, /* millisecond, opt_val type must be double, the access latency from client to DPI system */ + MSO_INTERNET_LATENCY, /* millisecond, opt_val type must be double, the internet latency from DPI system to server */ + MSO_TCP_STREAM_SRTT, /* millisecond, opt_val type must be double, the SRTT of current TCP stream */ + __MSO_MAX, +}; /* for MSO_STREAM_CLOSE_REASON, don't confuse, these values is not consecutive indeed, because some value(1,2) is obsoleted! diff --git a/module_test/src/gtest_main.cpp b/module_test/src/gtest_main.cpp index 6c09d49..6f4fa28 100644 --- a/module_test/src/gtest_main.cpp +++ b/module_test/src/gtest_main.cpp @@ -963,32 +963,22 @@ TEST(control, get_ip_ttl) ASSERT_EQ(GTEST_SAPP_SUCC, gtest_get_libsapp_devel_result()); } - -#define control_get_tcp_rtt 1 -TEST(control, get_tcp_rtt) +TEST(control, get_tcp_latency) { -#if 0 - //control_get_tcp_rtt_run(); - //ASSERT_EQ(GTEST_SAPP_SUCC, gtest_get_libsapp_devel_result()); -#else - EXPECT_EXIT(control_get_tcp_rtt_run(), testing::ExitedWithCode(0), "test succ"); -#endif + control_get_tcp_latency_run(); + ASSERT_EQ(GTEST_SAPP_SUCC, gtest_get_libsapp_devel_result()); } -#define control_get_tcp_rtt_c2s 1 -TEST(control, get_tcp_rtt_c2s) +TEST(control, get_tcp_latency_srtt) { - control_get_tcp_rtt_c2s_run(); + control_get_tcp_latency_srtt_run(); ASSERT_EQ(GTEST_SAPP_SUCC, gtest_get_libsapp_devel_result()); - // EXPECT_EXIT(control_get_tcp_rtt_run(), testing::ExitedWithCode(0), "test succ"); } -#define control_get_tcp_rtt_s2c 1 -TEST(control, get_tcp_rtt_s2c) +TEST(control, get_tcp_latency_srtt_long_duration) { - control_get_tcp_rtt_s2c_run(); + control_get_tcp_latency_srtt_long_duration_run(); ASSERT_EQ(GTEST_SAPP_SUCC, gtest_get_libsapp_devel_result()); - // EXPECT_EXIT(control_get_tcp_rtt_run(), testing::ExitedWithCode(0), "test succ"); } TEST(control, get_stream_uuid) diff --git a/module_test/src/gtest_sapp_fun.h b/module_test/src/gtest_sapp_fun.h index 3298c1e..96383ac 100644 --- a/module_test/src/gtest_sapp_fun.h +++ b/module_test/src/gtest_sapp_fun.h @@ -375,11 +375,11 @@ void get_linkdir_from_mac_run2(void); void get_deployment_mode_mirror(void); void get_deployment_mode_inline(void); void get_deployment_mode_transparent(void); -void control_get_ip_ttl_run(void); -void control_get_tcp_rtt_run(void); -void control_get_tcp_rtt_c2s_run(void); -void control_get_tcp_rtt_s2c_run(void); void control_get_stream_uuid_run(void); +void control_get_ip_ttl_run(void); +void control_get_tcp_latency_run(void); +void control_get_tcp_latency_srtt_run(void); +void control_get_tcp_latency_srtt_long_duration_run(void); /****************************** tunnel **************************/ void teredo_unstandard_port_run(void); void teredo_with_auth_hdr_run(void); diff --git a/module_test/src/gtest_sapp_support.cpp b/module_test/src/gtest_sapp_support.cpp index b252901..3562b39 100644 --- a/module_test/src/gtest_sapp_support.cpp +++ b/module_test/src/gtest_sapp_support.cpp @@ -1080,38 +1080,33 @@ void control_get_ip_ttl_run(void) call_libsapp_devel_for_dumpfile_topspeed(); } -void control_get_tcp_rtt_run(void) +void control_get_tcp_latency_run(void) { set_default_config(); - update_plugin_inf("IP", "iplayer_readjust_time_entry"); - append_plugin_inf("TCP", "get_tcp_rtt_entry"); - + append_plugin_inf("TCP", "get_tcp_latency_entry"); set_pcap_dumpfile("for_gtest_only/tcp/tcp_rtt.pcap"); ASSERT_EQ(file_md5_checksum("dumpfile", "1e06f7ed52405f9014bea2b117ecadff"),0); - call_libsapp_devel_for_dumpfile_topspeed(); } -void control_get_tcp_rtt_c2s_run(void) +void control_get_tcp_latency_srtt_run(void) { set_default_config(); - update_plugin_inf("TCP", "get_tcp_rtt_err_entry"); - - set_pcap_dumpfile("tcp/tcp_isn_c2s_single.pcap"); - ASSERT_EQ(file_md5_checksum("dumpfile", "a5d0d96ee6f44f729d79aeac5cc2fee0"),0); - + update_plugin_inf("IP", "iplayer_readjust_time_entry"); + append_plugin_inf("TCP", "get_tcp_latency_srtt_entry"); + set_pcap_dumpfile("for_gtest_only/tcp/tcp_http_rtt.pcap"); + ASSERT_EQ(file_md5_checksum("dumpfile", "4564f6d281528435288d2263e7947d5b"),0); call_libsapp_devel_for_dumpfile_topspeed(); } -void control_get_tcp_rtt_s2c_run(void) +void control_get_tcp_latency_srtt_long_duration_run(void) { set_default_config(); - update_plugin_inf("TCP", "get_tcp_rtt_err_entry"); - - set_pcap_dumpfile("for_gtest_only/tcp/tcp_rtt_s2c.pcap"); - ASSERT_EQ(file_md5_checksum("dumpfile", "006277b38aa1f9a0d272b643b8a3b686"),0); - + update_plugin_inf("IP", "iplayer_readjust_time_entry"); + append_plugin_inf("TCP", "get_tcp_latency_srtt_long_duration_entry"); + set_pcap_dumpfile("for_gtest_only/tcp/tcp_rtt_long_duration.pcap"); + ASSERT_EQ(file_md5_checksum("dumpfile", "ec0e5e1359c8a9352eeb7c6122944f90"),0); call_libsapp_devel_for_dumpfile_topspeed(); } diff --git a/module_test/src/gtest_sapp_support_plug.cpp b/module_test/src/gtest_sapp_support_plug.cpp index 7e462c5..071363e 100644 --- a/module_test/src/gtest_sapp_support_plug.cpp +++ b/module_test/src/gtest_sapp_support_plug.cpp @@ -2482,41 +2482,44 @@ extern "C" char get_ip_ttl_entry(struct streaminfo *pstream,void **pme, int thre return APP_STATE_GIVEME; } -extern "C" char get_tcp_rtt_entry(struct streaminfo *pstream, void **pme, int thread_seq, void *a_packet) +#endif + +extern "C" char get_tcp_latency_entry(struct streaminfo *pstream, void **pme, int thread_seq, void *a_packet) { - static unsigned short rtt_csc = 0, rtt_scs = 0; + static double internet_latency = 0.0, access_latency = 0.0; int ret; - int opt_len = sizeof(short); + int opt_len = sizeof(double); - if (pstream->opstate == OP_STATE_CLOSE) + if (pstream->opstate == OP_STATE_DATA) { - ret = MESA_get_stream_opt(pstream, MSO_TCP_RTT_CSC, &rtt_csc, &opt_len); + ret = MESA_get_stream_opt(pstream, MSO_INTERNET_LATENCY, &internet_latency, &opt_len); if (ret < 0) { - fprintf(stderr, "\033[1;31;40mget_tcp_rtt_entry error: get MSO_TCP_RTT_CSC test fail!\033[0m\n"); + fprintf(stderr, "\033[1;31;40mget_tcp_rtt_entry error: get MSO_INTERNET_LATENCY test fail!\033[0m\n"); gtest_set_libsapp_devel_result(GTEST_SAPP_ERR); exit(1); return APP_STATE_DROPME; } - ret = MESA_get_stream_opt(pstream, MSO_TCP_RTT_SCS, &rtt_scs, &opt_len); + ret = MESA_get_stream_opt(pstream, MSO_ACCESS_LATENCY, &access_latency, &opt_len); if (ret < 0) { - fprintf(stderr, "\033[1;31;40mget_tcp_rtt_entry error: get MSO_TCP_RTT_SCS test fail!\033[0m\n"); + fprintf(stderr, "\033[1;31;40mget_tcp_rtt_entry error: get MSO_ACCESS_LATENCY test fail!\033[0m\n"); gtest_set_libsapp_devel_result(GTEST_SAPP_ERR); exit(1); return APP_STATE_DROPME; } - /* in pcap, actual latency is 65ms, scs is 143ms, an error of 3 microseconds is allowed */ - if (rtt_csc >= 62 && rtt_csc <= 68 && rtt_scs >= 141 && rtt_scs <= 146) + /* in pcap, actual internet latency is 33ms, access latency is 71ms, an accuracy error within 1 microseconds is allowed */ + if (internet_latency >= 32 && internet_latency <= 34 && access_latency >= 70 && access_latency <= 72) { fprintf(stderr, "\033[32mget_tcp_rtt_entry test succ \033[0m\n"); gtest_set_libsapp_devel_result(GTEST_SAPP_SUCC); exit(0); return APP_STATE_DROPME; }else{ - fprintf(stderr, "\033[1;31;40mget_tcp_rtt_entry error: get rtt_csc:%d, but expect:%d, get rtt_scs:%d, but expect:%d\033[0m\n", rtt_csc, 65, rtt_scs, 143); + fprintf(stderr, "\033[1;31;40mget_tcp_rtt_entry error: get internet_latency:%f, but expect:%d, get access_latency:%f, but expect:%d\033[0m\n", + internet_latency, 31, access_latency, 71); gtest_set_libsapp_devel_result(GTEST_SAPP_ERR); exit(1); return APP_STATE_DROPME; @@ -2525,31 +2528,65 @@ extern "C" char get_tcp_rtt_entry(struct streaminfo *pstream, void **pme, int th return APP_STATE_GIVEME; } -extern "C" char get_tcp_rtt_err_entry(struct streaminfo *pstream, void **pme, int thread_seq, void *a_packet) +extern "C" char get_tcp_latency_srtt_entry(struct streaminfo *pstream, void **pme, int thread_seq, void *a_packet) { - unsigned short rtt_csc = 0xFFFF, rtt_scs = 0xFFFF; + static double internet_latency = 0.0, access_latency = 0.0; int ret; - int opt_len = sizeof(short); + int opt_len = sizeof(double); - if(OP_STATE_CLOSE == pstream->opstate){ - ret = MESA_get_stream_opt(pstream, MSO_TCP_RTT_CSC, &rtt_csc, &opt_len); - if(ret >= 0 || rtt_csc != 0xFFFF){ - fprintf(stderr, "\033[1;31;40mget_tcp_rtt_err_entry error: get rtt_csc, but expect not!\033[0m\n"); + if (pstream->opstate == OP_STATE_DATA) + { + ret = MESA_get_stream_opt(pstream, MSO_INTERNET_LATENCY, &internet_latency, &opt_len); + if (ret < 0) + { + fprintf(stderr, "\033[1;31;40mget_tcp_latency_srtt_entry error: get MSO_INTERNET_LATENCY test fail!\033[0m\n"); gtest_set_libsapp_devel_result(GTEST_SAPP_ERR); + exit(1); return APP_STATE_DROPME; } - ret = MESA_get_stream_opt(pstream, MSO_TCP_RTT_SCS, &rtt_scs, &opt_len); - if(ret >= 0 || rtt_scs != 0xFFFF){ - fprintf(stderr, "\033[1;31;40mget_tcp_rtt_err_entry error: get rtt_scs, but expect not!\033[0m\n"); + + ret = MESA_get_stream_opt(pstream, MSO_ACCESS_LATENCY, &access_latency, &opt_len); + if (ret < 0) + { + fprintf(stderr, "\033[1;31;40mget_tcp_latency_srtt_entry error: get MSO_ACCESS_LATENCY test fail!\033[0m\n"); gtest_set_libsapp_devel_result(GTEST_SAPP_ERR); + exit(1); return APP_STATE_DROPME; - } + } - fprintf(stderr, "\033[32mget_tcp_rtt_error_entry test succ \033[0m\n"); - gtest_set_libsapp_devel_result(GTEST_SAPP_SUCC); - return APP_STATE_DROPME; + /* in pcap, actual internet latency is 600ms, access latency is 14ms, an accuracy error within 1 microseconds is allowed */ + if (internet_latency < 599 || internet_latency > 601 || access_latency < 13 || access_latency > 15) + { + fprintf(stderr, "\033[1;31;40mget_tcp_latency_srtt_entry error: get internet_latency:%f, but expect:%f, get access_latency:%f, but expect:%f\033[0m\n", + internet_latency, (double)600, access_latency, (double)14); + gtest_set_libsapp_devel_result(GTEST_SAPP_ERR); + exit(1); + return APP_STATE_DROPME; + } } + if (pstream->opstate == OP_STATE_CLOSE) + { + double srtt = 0.0; + opt_len = sizeof(double); + ret = MESA_get_stream_opt(pstream, MSO_TCP_STREAM_SRTT, &srtt, &opt_len); + if (ret < 0) + { + fprintf(stderr, "\033[1;31;40mget_tcp_latency_srtt_entry error: get MSO_TCP_STREAM_SRTT test fail!\033[0m\n"); + gtest_set_libsapp_devel_result(GTEST_SAPP_ERR); + exit(1); + return APP_STATE_DROPME; + } + if (srtt < 1227 || srtt > 1229)//initialize srtt is 1228ms + { + fprintf(stderr, "\033[1;31;40mget_tcp_latency_srtt_entry error: get srtt:%f, but expect:%f \033[0m\n",srtt, (double)1228); + gtest_set_libsapp_devel_result(GTEST_SAPP_ERR); + exit(1); + return APP_STATE_DROPME; + } + fprintf(stderr, "\033[32mget_tcp_latency_srtt_entry test succ \033[0m\n"); + gtest_set_libsapp_devel_result(GTEST_SAPP_SUCC); + } return APP_STATE_GIVEME; } @@ -2588,7 +2625,64 @@ extern "C" char ctrl_get_stream_uuid_entry(struct streaminfo *pstream, void **pm return APP_STATE_GIVEME; } -#endif +extern "C" char get_tcp_latency_srtt_long_duration_entry(struct streaminfo *pstream, void **pme, int thread_seq, void *a_packet) +{ + static double internet_latency = 0.0, access_latency = 0.0; + int ret; + int opt_len = sizeof(double); + if (pstream->opstate == OP_STATE_DATA) + { + ret = MESA_get_stream_opt(pstream, MSO_INTERNET_LATENCY, &internet_latency, &opt_len); + if (ret < 0) + { + fprintf(stderr, "\033[1;31;40mget_tcp_latency_srtt_entry error: get MSO_INTERNET_LATENCY test fail!\033[0m\n"); + gtest_set_libsapp_devel_result(GTEST_SAPP_ERR); + exit(1); + return APP_STATE_DROPME; + } + ret = MESA_get_stream_opt(pstream, MSO_ACCESS_LATENCY, &access_latency, &opt_len); + if (ret < 0) + { + fprintf(stderr, "\033[1;31;40mget_tcp_latency_srtt_entry error: get MSO_ACCESS_LATENCY test fail!\033[0m\n"); + gtest_set_libsapp_devel_result(GTEST_SAPP_ERR); + exit(1); + return APP_STATE_DROPME; + } + /* in pcap, actual internet latency is 2ms, access latency is approximately 0ms, an accuracy error within 1 microseconds is allowed */ + if (internet_latency < 1 || internet_latency > 3 || access_latency < -1.0 || access_latency > 1) + { + fprintf(stderr, "\033[1;31;40mget_tcp_latency_srtt_entry error: get internet_latency:%f, but expect:%f, get access_latency:%f, but expect:%f\033[0m\n", + internet_latency, (double)600, access_latency, (double)14); + gtest_set_libsapp_devel_result(GTEST_SAPP_ERR); + exit(1); + return APP_STATE_DROPME; + } + } + + if (pstream->opstate == OP_STATE_CLOSE) + { + double srtt = 0.0; + opt_len = sizeof(double); + ret = MESA_get_stream_opt(pstream, MSO_TCP_STREAM_SRTT, &srtt, &opt_len); + if (ret < 0) + { + fprintf(stderr, "\033[1;31;40mget_tcp_latency_srtt_entry error: get MSO_TCP_STREAM_SRTT test fail!\033[0m\n"); + gtest_set_libsapp_devel_result(GTEST_SAPP_ERR); + exit(1); + return APP_STATE_DROPME; + } + if (srtt < 5 || srtt > 8)//initialize srtt is approximately 6~7 ms + { + fprintf(stderr, "\033[1;31;40mget_tcp_latency_srtt_entry error: get srtt:%f, but expect:%f \033[0m\n",srtt, (double)6.8); + gtest_set_libsapp_devel_result(GTEST_SAPP_ERR); + exit(1); + return APP_STATE_DROPME; + } + fprintf(stderr, "\033[32mget_tcp_latency_srtt_entry test succ \033[0m\n"); + gtest_set_libsapp_devel_result(GTEST_SAPP_SUCC); + } + return APP_STATE_GIVEME; +} diff --git a/src/dealpkt/deal_tcp.c b/src/dealpkt/deal_tcp.c index 9699adb..b7fd0bd 100644 --- a/src/dealpkt/deal_tcp.c +++ b/src/dealpkt/deal_tcp.c @@ -39,7 +39,7 @@ static void packet_io_status_tcp_pkt_update(int tid, unsigned char tcp_flags, in static int tcp_deal_unorder(struct streamindex *pindex,struct streaminfo *a_tcp, struct half_tcpstream *rcv, struct half_tcpstream *snd,int orderflag); - + inline static int before (u_int seq1, u_int seq2) { return ((int) (seq1 - seq2) < 0); @@ -653,14 +653,23 @@ static struct streamindex *tcp_add_new_stream_bysyn(struct streamindex *pindex, pdetail->clientbytes+= datalen; /* 2014-12-19 lijia add, for SYN pkt append data */ pdetail_pr->last_s2c_pkt_rcv_time = ABBR_CURRENT_TIME_MS; pdetail_pr->S2C_ack_seq = ntohl(this_tcphdr->th_ack); + sapp_runtime_log(RLOG_LV_DEBUG, "add_new_by_syn()->S2C TCP PKT timestamp: stream:%s, current_ms=%lld, seq=%u, ack=%u, chksum=0x%x", + printaddr(&pstream->addr, pstream->threadnum), ABBR_CURRENT_TIME_MS, + ntohl(this_tcphdr->th_seq), ntohl(this_tcphdr->th_ack), ntohs(this_tcphdr->th_sum)); }else if(createdir==DIR_C2S){ pdetail->serverpktnum++; pdetail->serverbytes+= datalen;/* 2014-12-19 lijia add, for SYN pkt append data */ pdetail_pr->last_c2s_pkt_rcv_time = ABBR_CURRENT_TIME_MS; pdetail_pr->C2S_ack_seq = ntohl(this_tcphdr->th_ack); + sapp_runtime_log(RLOG_LV_DEBUG, "add_new_by_syn()->C2S TCP PKT timestamp: stream:%s, current_ms=%lld, seq=%u, ack=%u, chksum=0x%x", + printaddr(&pstream->addr, pstream->threadnum), ABBR_CURRENT_TIME_MS, + ntohl(this_tcphdr->th_seq), ntohl(this_tcphdr->th_ack), ntohs(this_tcphdr->th_sum)); } - pdetail_pr->rtt_csc = 0xFFFF; - pdetail_pr->rtt_scs = 0xFFFF; + pdetail_pr->internet_latency = DBL_MAX; + pdetail_pr->access_latency = DBL_MAX; + pdetail_pr->srtt_metric.rtt_dpi_client_dpi = 0xFFFF; + pdetail_pr->srtt_metric.rtt_dpi_server_dpi = 0xFFFF; + pdetail_pr->srtt_metric.srtt = DBL_MAX; } else { @@ -694,6 +703,12 @@ static struct streamindex *tcp_add_new_stream_bysyn(struct streamindex *pindex, pdetail->createtime=g_CurrentTime; pstream_pr->stream_create_timestamp_ms=g_CurrentTime_ms; + pdetail_pr->internet_latency = DBL_MAX; + pdetail_pr->access_latency = DBL_MAX; + pdetail_pr->srtt_metric.rtt_dpi_client_dpi = 0xFFFF; + pdetail_pr->srtt_metric.rtt_dpi_server_dpi = 0xFFFF; + pdetail_pr->srtt_metric.srtt = DBL_MAX; + /* ????????, ?????��????ddos ?? */ if(pstream_pr->create_dir_by_well_known_port != 1) { @@ -1307,6 +1322,12 @@ int tcp_free_stream(struct streamindex *pindex, const void *this_ip_hdr, const v UCHAR threadnum = pstream->threadnum; int pkt_ret = PASS; + sapp_runtime_log(RLOG_LV_DEBUG, "tcp_free_stream():%s srtt measurement result: access_latency=%.3fms, internet_latency=%.3fms, srtt=%.3fms", + printaddr(&pstream->addr, pstream->threadnum), + pdetail_pr->access_latency == DBL_MAX ? 0.0 : pdetail_pr->access_latency, + pdetail_pr->internet_latency == DBL_MAX ? 0.0 : pdetail_pr->internet_latency, + pdetail_pr->srtt_metric.srtt == DBL_MAX ? 0.0 : pdetail_pr->srtt_metric.srtt); + tcp_update_close_reason_stat(threadnum, pdetail_pr); plist=&(G_MESA_GLOBAL_STREAM[threadnum]->tcpList[pstream->stream_state]); @@ -1567,36 +1588,140 @@ static int tcp_reset_stream(struct streamindex *pindex,const void *this_iphdr, return ret; } -static void inline calculate_tcp_rtt(const struct streaminfo *pstream, struct tcpdetail_private *pdetail_pr, const struct mesa_tcp_hdr *this_tcphdr) +static void inline calculate_tcp_handshake_latency(const struct streaminfo *pstream, struct tcpdetail_private *pdetail_pr, const struct mesa_tcp_hdr *this_tcphdr) { - if(pdetail_pr->tcpdetail_public.clientpktnum < 1 || pdetail_pr->tcpdetail_public.serverpktnum < 1) - { + if(pdetail_pr->tcpdetail_public.clientpktnum < 1 + || pdetail_pr->tcpdetail_public.serverpktnum < 1 + || pstream->stream_state != TCP_SYN_STATE){ return; } - if(pdetail_pr->rtt_csc != 0xFFFF && pdetail_pr->rtt_scs != 0xFFFF) - { - return; - } + unsigned int th_flags = this_tcphdr->th_flags; unsigned int cur_tcp_ack = ntohl(this_tcphdr->th_ack); + unsigned int cur_tcp_seq = ntohl(this_tcphdr->th_seq); - if(pstream->curdir == DIR_C2S) - { - unsigned int cur_tcp_seq = ntohl(this_tcphdr->th_seq); - if(pdetail_pr->iclientseq == cur_tcp_ack && pdetail_pr->S2C_ack_seq == cur_tcp_seq) - { - pdetail_pr->rtt_scs = ABBR_CURRENT_TIME_MS - pdetail_pr->last_s2c_pkt_rcv_time; + if(pstream->curdir == DIR_C2S){ + if(cur_tcp_seq == pdetail_pr->iserverseq && pdetail_pr->iclientseq == cur_tcp_ack){ + pdetail_pr->access_latency = ((double)ABBR_CURRENT_TIME_MS - (double)pdetail_pr->last_s2c_pkt_rcv_time)/2; + pdetail_pr->srtt_metric.rtt_dpi_client_dpi = ABBR_CURRENT_TIME_MS - pdetail_pr->last_s2c_pkt_rcv_time; + sapp_runtime_log(RLOG_LV_DEBUG, "tcp_handshake_latency stream:%s, C2S, current_ms=%lld, seq=%u, ack=%u, chksum=0x%x, access_latency=%.3fms", + printaddr(&pstream->addr, pstream->threadnum), ABBR_CURRENT_TIME_MS, + ntohl(this_tcphdr->th_seq), ntohl(this_tcphdr->th_ack), ntohs(this_tcphdr->th_sum), pdetail_pr->access_latency); } - } - else - { - if(pdetail_pr->iserverseq == cur_tcp_ack) - { - pdetail_pr->rtt_csc = ABBR_CURRENT_TIME_MS - pdetail_pr->last_c2s_pkt_rcv_time; + }else{ // DIR_S2C + if(th_flags == (TH_SYN|TH_ACK) && pdetail_pr->iserverseq == cur_tcp_ack){ + pdetail_pr->internet_latency = ((double)ABBR_CURRENT_TIME_MS - (double)pdetail_pr->last_c2s_pkt_rcv_time)/2; + pdetail_pr->srtt_metric.rtt_dpi_server_dpi = ABBR_CURRENT_TIME_MS - pdetail_pr->last_c2s_pkt_rcv_time; + sapp_runtime_log(RLOG_LV_DEBUG, "tcp_handshake_latency stream:%s, S2C, current_ms=%lld, seq=%u, ack=%u, chksum=0x%x, internet_latency=%.3fms", + printaddr(&pstream->addr, pstream->threadnum), ABBR_CURRENT_TIME_MS, + ntohl(this_tcphdr->th_seq), ntohl(this_tcphdr->th_ack), ntohs(this_tcphdr->th_sum), pdetail_pr->internet_latency); } } return; } +/* + EWMA: Exponentially Weighted Moving Average +*/ +static inline void tcp_srtt_update(struct tcp_srtt_metric *srtt_metric, double current_rtt) +{ + if(DOUBLE_IS_ZERO(current_rtt)){ + return; + } + double new_srtt = current_rtt * TCP_SRTT_EWMA_ALPHA + (1 - TCP_SRTT_EWMA_ALPHA) * srtt_metric->srtt; + srtt_metric->srtt = new_srtt; +} + +static void tcp_srtt_measurement(const struct streaminfo *pstream, struct tcpdetail_private *pdetail_pr, const struct mesa_tcp_hdr *this_tcphdr) +{ + struct tcp_srtt_metric *srtt_metric = &pdetail_pr->srtt_metric; + if(pstream->dir != DIR_DOUBLE){ + return; + } + if(pstream->addr.pkttype & PKT_TYPE_TCPRETRANS + || pstream->addr.pkttype & PKT_TYPE_TCPREORDER + || pstream->addr.pkttype & PKT_TYPE_TCPUNORDER){ + return; //ignore tcp retransmission, unorder packets + } + + struct streaminfo_private *pstream_pr = container_of(pstream, struct streaminfo_private, stream_public); + if(pstream_pr->raw_pkt && pstream_pr->raw_pkt->is_ctrl_pkt){ + return; + } + + if(DBL_MAX == pdetail_pr->srtt_metric.srtt){ + if(pdetail_pr->internet_latency == DBL_MAX || pdetail_pr->access_latency == DBL_MAX){ + sapp_runtime_log(RLOG_LV_INFO, "tcp_srtt_measurement error: stream:%s, can't get handshake latency!", + printaddr(&pstream->addr, pstream->threadnum)); + return; + } + pdetail_pr->srtt_metric.srtt = 0.0; //set initialize rtt from handshake latency + if(pdetail_pr->internet_latency != DBL_MAX){ + pdetail_pr->srtt_metric.srtt += (double)pdetail_pr->internet_latency * 2; + } + if(pdetail_pr->access_latency != DBL_MAX){ + pdetail_pr->srtt_metric.srtt += (double)pdetail_pr->access_latency * 2; + } + } + + const struct half_tcpstream *rcv; + uint32_t cur_ack = ntohl(this_tcphdr->th_ack); + + if(DIR_C2S == pstream->curdir){ + if(0 == pdetail_pr->last_s2c_pkt_rcv_time){ + return; + } + rcv = pdetail_pr->pclient; + if(rcv && (EXP_SEQ == cur_ack)){ + srtt_metric->rtt_dpi_client_dpi = ABBR_CURRENT_TIME_MS - pdetail_pr->last_s2c_pkt_rcv_time; + sapp_runtime_log(RLOG_LV_DEBUG, "tcp_srtt_measurement: stream:%s, current_ms=%lld, seq=%u, ack=%u, chksum=0x%x, rtt_dpi_client_dpi=%u", + printaddr(&pstream->addr, pstream->threadnum), ABBR_CURRENT_TIME_MS, + ntohl(this_tcphdr->th_seq), ntohl(this_tcphdr->th_ack), ntohs(this_tcphdr->th_sum), srtt_metric->rtt_dpi_client_dpi); + pdetail_pr->last_s2c_pkt_rcv_time = 0; + }else{ + sapp_runtime_log(RLOG_LV_DEBUG, "TCP stream:%s into srtt measurement(), curdir=%d, but not expect seq! EXP_SEQ=%x, curack=%x", + printaddr(&pstream->addr, pstream->threadnum), pstream->curdir, EXP_SEQ, cur_ack); + } + } + else //DIR_S2C + { + if(0 == pdetail_pr->last_c2s_pkt_rcv_time){ + return; + } + rcv = pdetail_pr->pserver; + if(rcv && (EXP_SEQ == cur_ack)){ + srtt_metric->rtt_dpi_server_dpi = ABBR_CURRENT_TIME_MS - pdetail_pr->last_c2s_pkt_rcv_time; + sapp_runtime_log(RLOG_LV_DEBUG, "tcp_srtt_measurement: stream:%s, current_ms=%lld, seq=%u, ack=%u, chksum=0x%x, rtt_dpi_server_dpi=%u", + printaddr(&pstream->addr, pstream->threadnum), ABBR_CURRENT_TIME_MS, + ntohl(this_tcphdr->th_seq), ntohl(this_tcphdr->th_ack), ntohs(this_tcphdr->th_sum), srtt_metric->rtt_dpi_server_dpi); + pdetail_pr->last_c2s_pkt_rcv_time = 0; + }else{ + sapp_runtime_log(RLOG_LV_DEBUG, "TCP stream:%s into srtt measurement(), curdir=%d, but not expect seq! EXP_SEQ=%x, curack=%x", + printaddr(&pstream->addr, pstream->threadnum), pstream->curdir, EXP_SEQ, cur_ack); + } + } + + //sampling rtt every TCP_SAMPLING_SRTT_INTERVAL_MS + if(pdetail_pr->srtt_metric.last_rtt_sampling_time + TCP_SAMPLING_SRTT_INTERVAL_MS > ABBR_CURRENT_TIME_MS){ + return; + } + + if(srtt_metric->rtt_dpi_client_dpi != 0xFFFF + && srtt_metric->rtt_dpi_server_dpi != 0xFFFF + && (srtt_metric->rtt_dpi_client_dpi + srtt_metric->rtt_dpi_server_dpi > 0) ){ + double last_rtt = srtt_metric->srtt; + double current_rtt = (double)(srtt_metric->rtt_dpi_client_dpi + srtt_metric->rtt_dpi_server_dpi); + tcp_srtt_update(srtt_metric, current_rtt); + sapp_runtime_log(RLOG_LV_DEBUG, "TCP stream:%s srtt measurement update: seq=%u, ack=%u, chksum=0x%x, last rtt: %f, current_rtt: %f(rtt_dpi_client_dpi=%f, rtt_dpi_server_dpi=%f), new_srtt: %f, access_latency=%.3fms, internet_latency=%.3fms", + printaddr(&pstream->addr, pstream->threadnum), + ntohl(this_tcphdr->th_seq), ntohl(this_tcphdr->th_ack), ntohs(this_tcphdr->th_sum), + last_rtt, current_rtt, srtt_metric->rtt_dpi_client_dpi, srtt_metric->rtt_dpi_server_dpi, + srtt_metric->srtt, pdetail_pr->access_latency, pdetail_pr->internet_latency); + srtt_metric->last_rtt_sampling_time = ABBR_CURRENT_TIME_MS; + srtt_metric->rtt_dpi_client_dpi = 0xFFFF; /* reset after use */ + srtt_metric->rtt_dpi_server_dpi = 0xFFFF; /* reset after use */ + } +} + //static int tcp_deal_syn_stream(struct streamindex *pindex,struct mesa_tcp_hdr *this_tcphdr,int datalen) static int tcp_deal_syn_stream(struct streamindex *pindex,const raw_pkt_t *raw_pkt, const void *this_iphdr, struct mesa_tcp_hdr *this_tcphdr,int datalen) @@ -1610,15 +1735,24 @@ static int tcp_deal_syn_stream(struct streamindex *pindex,const raw_pkt_t *raw_p int thisseq=ntohl (this_tcphdr->th_seq); int thisack=ntohl (this_tcphdr->th_ack); - calculate_tcp_rtt(pstream, pdetail_pr, this_tcphdr); - + calculate_tcp_handshake_latency(pstream, pdetail_pr, this_tcphdr); + if (curdir == DIR_C2S){ + pdetail_pr->last_c2s_pkt_rcv_time = ABBR_CURRENT_TIME_MS; + sapp_runtime_log(RLOG_LV_DEBUG, "deal_syn_stream()->C2S TCP PKT timestamp: stream:%s, current_ms=%lld, seq=%u, ack=%u, chksum=0x%x", + printaddr(&pstream->addr, pstream->threadnum), ABBR_CURRENT_TIME_MS, + ntohl(this_tcphdr->th_seq), ntohl(this_tcphdr->th_ack), ntohs(this_tcphdr->th_sum)); + }else{ + pdetail_pr->last_s2c_pkt_rcv_time = ABBR_CURRENT_TIME_MS; + sapp_runtime_log(RLOG_LV_DEBUG, "deal_syn_stream()->S2C TCP PKT timestamp: stream:%s, current_ms=%lld, seq=%u, ack=%u, chksum=0x%x", + printaddr(&pstream->addr, pstream->threadnum), ABBR_CURRENT_TIME_MS, + ntohl(this_tcphdr->th_seq), ntohl(this_tcphdr->th_ack), ntohs(this_tcphdr->th_sum)); + } if (pstream->dir == DIR_C2S) { curseq = pdetail_pr->iserverseq; if (curdir == DIR_S2C) { pdetail_pr->S2C_ack_seq = thisack; - pdetail_pr->last_s2c_pkt_rcv_time = ABBR_CURRENT_TIME_MS; if ((this_tcphdr->th_flags & TH_RST) && (datalen == 0)) { if (thisack == curseq) @@ -1649,7 +1783,6 @@ static int tcp_deal_syn_stream(struct streamindex *pindex,const raw_pkt_t *raw_p else { pdetail_pr->C2S_ack_seq = thisack; - pdetail_pr->last_c2s_pkt_rcv_time = ABBR_CURRENT_TIME_MS; if (thisseq == curseq) { if ((this_tcphdr->th_flags & TH_RST) && (datalen == 0)) @@ -1677,7 +1810,6 @@ static int tcp_deal_syn_stream(struct streamindex *pindex,const raw_pkt_t *raw_p if (curdir == DIR_C2S) { - pdetail_pr->last_c2s_pkt_rcv_time = ABBR_CURRENT_TIME_MS; if ((this_tcphdr->th_flags & TH_RST) && (datalen == 0)) { pstream->dir = DIR_DOUBLE; @@ -1697,7 +1829,6 @@ static int tcp_deal_syn_stream(struct streamindex *pindex,const raw_pkt_t *raw_p } else { - pdetail_pr->last_s2c_pkt_rcv_time = ABBR_CURRENT_TIME_MS; if ((thisseq == curseq) && (this_tcphdr->th_flags & TH_RST) && (datalen == 0)) { @@ -1723,14 +1854,14 @@ static int tcp_deal_syn_stream(struct streamindex *pindex,const raw_pkt_t *raw_p { pdetail_pr->iserverseq=thisseq + 1; pdetail_pr->multisynflag=1; - pdetail_pr->tcpstateflag=TCP_SYN_SENT; + pdetail_pr->tcpstateflag=TCP_SYN_SENT; } if(this_tcphdr->th_flags == (TH_SYN|TH_ACK)) { pdetail_pr->iclientseq=thisseq+1; pdetail_pr->multisynflag=1; - pdetail_pr->tcpstateflag=TCP_SYN_SENT; + pdetail_pr->tcpstateflag=TCP_SYN_SENT; } return PASS; @@ -2194,6 +2325,7 @@ static int tcp_deal_data(struct streamindex *pindex,const void *this_iphdr,const if (after(this_seq + datalen + (this_tcphdr->th_flags & TH_FIN), EXP_SEQ)) { + tcp_srtt_measurement(pstream, pdetail_pr, this_tcphdr); tcp_set_new_data(pstream,rcv,snd,tcpdata,datalen,this_seq,this_tcphdr->th_flags & TH_FIN, raw_pkt->is_ctrl_pkt); if(datalen >0) { @@ -2402,6 +2534,7 @@ static int tcp_deal_data_stream(struct streamindex *pindex,const void *this_iphd return ret; } } + tcp_srtt_measurement(pstream, pdetail_pr, this_tcphdr); if(pstream->dir==DIR_DOUBLE) { @@ -2650,6 +2783,26 @@ static int deal_tcp_tfo(struct streaminfo *pstream, const void *this_iphdr, stru return ret; } +static inline void tcp_update_last_pkt_time(struct streaminfo_private *pstream_pr, int tcplen) +{ + struct tcpdetail_private * pdetail_pr = (struct tcpdetail_private *)(pstream_pr->stream_public.pdetail); + if(pdetail_pr){ + if(DIR_C2S == pstream_pr->stream_public.curdir){ + if(tcplen > 0 || pstream_pr->stream_public.stream_state == TCP_SYN_STATE){ + pdetail_pr->last_c2s_pkt_rcv_time = ABBR_CURRENT_TIME_MS; + }else{ + pdetail_pr->last_c2s_pkt_rcv_time = 0; + } + }else{ + if(tcplen > 0 || pstream_pr->stream_public.stream_state == TCP_SYN_STATE){ + pdetail_pr->last_s2c_pkt_rcv_time = ABBR_CURRENT_TIME_MS; + }else{ + pdetail_pr->last_s2c_pkt_rcv_time = 0; + } + } + } +} + //int deal_tcp_stream(struct streamindex *pstream,struct mesa_tcp_hdr *this_tcphdr,int tcplen,const void *rawippkt,int iplen) static int deal_tcp_stream(struct streamindex *pindex, const void *this_iphdr, struct mesa_tcp_hdr *this_tcphdr, int tcplen,const raw_pkt_t *raw_pkt, int offset_to_raw_pkt_hdr) @@ -2704,6 +2857,7 @@ static int deal_tcp_stream(struct streamindex *pindex, const void *this_iphdr, s } } } + tcp_update_last_pkt_time(pstream_pr, this_tcphdr->th_flags & TH_SYN); //The SYN packets consume one sequence number return ret; } else @@ -2824,6 +2978,9 @@ static int deal_tcp_stream(struct streamindex *pindex, const void *this_iphdr, s } pdetail->clientbytes+=tcplen; pdetail->clientpktnum++; + if(pdetail_pr->last_s2c_pkt_rcv_time != 0){ + pdetail_pr->srtt_metric.half_pkt_interval_s2c = ABBR_CURRENT_TIME_MS - pdetail_pr->last_s2c_pkt_rcv_time; + } } else { @@ -2833,6 +2990,9 @@ static int deal_tcp_stream(struct streamindex *pindex, const void *this_iphdr, s } pdetail->serverbytes+=tcplen; pdetail->serverpktnum++; + if(pdetail_pr->last_c2s_pkt_rcv_time != 0){ + pdetail_pr->srtt_metric.half_pkt_interval_c2s = ABBR_CURRENT_TIME_MS - pdetail_pr->last_c2s_pkt_rcv_time; + } } if(try_to_update_addr_info == 1) @@ -3011,16 +3171,15 @@ fun_exit: sapp_runtime_log(RLOG_LV_DEBUG, "TCP stream: %s, tcphdr->checksum:0x%x, curdir:%d, return DROP.", printaddr(&pstream->addr, pstream->threadnum), ntohs(this_tcphdr->th_sum), pstream->curdir); } - + if(raw_pkt->is_ctrl_pkt == 0){ + tcp_update_last_pkt_time(pstream_pr, tcplen); + } return ret; } - static int dealtcppkt(struct streamindex *pfindex, const void *this_iphdr, struct mesa_tcp_hdr *this_tcphdr, int thread_num,unsigned char routedir, int tcpdatalen, const raw_pkt_t *raw_packet, int offset_to_raw_pkt_hdr) { - - //struct streamindex tmp_tcp_stream; //struct streamindex *ptmp=&tmp_tcp_stream; struct streaminfo_private *pstream_pr = (struct streaminfo_private *)(&pfindex->stream); @@ -3057,7 +3216,11 @@ static int dealtcppkt(struct streamindex *pfindex, const void *this_iphdr, struc local_sys_stat->count_per_layer[ADDR_TYPE_TCP][pstream_pr->layer_index]++; local_sys_stat->length_per_layer[ADDR_TYPE_TCP][pstream_pr->layer_index] += tcpdatalen + this_tcphdr->th_off*4; - + + sapp_runtime_log(RLOG_LV_DEBUG, "TCP PKT timestamp: stream:%s, current_ms=%lld, seq=%u, ack=%u, chksum=0x%x, len=%d", + printaddr(&pstream->addr, pstream->threadnum), ABBR_CURRENT_TIME_MS, + ntohl(this_tcphdr->th_seq), ntohl(this_tcphdr->th_ack), ntohs(this_tcphdr->th_sum), tcpdatalen); + //return deal_tcp_stream(ptmp,this_tcphdr,tcpdatalen,raw_packet,raw_len); return deal_tcp_stream(pfindex,this_iphdr, this_tcphdr,tcpdatalen, raw_packet, offset_to_raw_pkt_hdr); } diff --git a/src/dealpkt/plug_support.c b/src/dealpkt/plug_support.c index 0542394..62360b0 100644 --- a/src/dealpkt/plug_support.c +++ b/src/dealpkt/plug_support.c @@ -2143,33 +2143,62 @@ int MESA_get_stream_opt(const struct streaminfo *pstream, enum MESA_stream_opt o case MSO_TCP_RTT_CSC: { + sapp_runtime_log(RLOG_LV_FATAL, "%s,MESA_get_stream_opt() MSO_TCP_RTT_CSC is deprecated!\n", printaddr(&pstream->addr, pstream->threadnum)); + ret = -1; + } + break; + case MSO_TCP_RTT_SCS: + { + sapp_runtime_log(RLOG_LV_FATAL, "%s,MESA_get_stream_opt() MSO_TCP_RTT_SCS is deprecated!\n", printaddr(&pstream->addr, pstream->threadnum)); + ret = -1; + } + break; + + case MSO_ACCESS_LATENCY: + { if(STREAM_TYPE_TCP != pstream->type){ - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TCP_RTT_CSC error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum)); + sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_ACCESS_LATENCY error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum)); ret = -1; break; } - if(0xFFFF == pdetail_pr->rtt_csc){ + if(DBL_MAX == pdetail_pr->access_latency){ ret = -1; break; } - *((unsigned short *)opt_val) = pdetail_pr->rtt_csc; - *opt_val_len = sizeof(short); + *((double *)opt_val) = pdetail_pr->access_latency; + *opt_val_len = sizeof(double); } break; - case MSO_TCP_RTT_SCS: + case MSO_INTERNET_LATENCY: + { + if(STREAM_TYPE_TCP != pstream->type){ + sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_INTERNET_LATENCY error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum)); + ret = -1; + break; + } + if(DBL_MAX == pdetail_pr->internet_latency){ + ret = -1; + break; + } + *((double *)opt_val) = pdetail_pr->internet_latency; + *opt_val_len = sizeof(double); + } + break; + + case MSO_TCP_STREAM_SRTT: { if(STREAM_TYPE_TCP != pstream->type){ - sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TCP_RTT_CSC error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum)); + sapp_runtime_log(RLOG_LV_INFO, "%s,MESA_get_stream_opt() MSO_TCP_STREAM_SRTT error:stream type is not tcp!\n", printaddr(&pstream->addr, pstream->threadnum)); ret = -1; break; } - if(0xFFFF == pdetail_pr->rtt_scs){ + if(DBL_MAX == pdetail_pr->srtt_metric.srtt){ ret = -1; break; } - *((unsigned short *)opt_val) = pdetail_pr->rtt_scs; - *opt_val_len = sizeof(short); + *((double *)opt_val) = pdetail_pr->srtt_metric.srtt; + *opt_val_len = sizeof(double); } break; diff --git a/test/test_app_sapp.c b/test/test_app_sapp.c index 3e8104c..c455224 100644 --- a/test/test_app_sapp.c +++ b/test/test_app_sapp.c @@ -45,7 +45,7 @@ typedef struct{ int test_bridge_id; }test_app_val_t; -/* ����һЩȫ�ֱ���, �и��ֲ�ͬ������, ��������������ݲ���, +/* ����һЩȫ�ֱ���, �и��ֲ�ͬ������, ��������������ݲ��?, �����������ɸ��������Լ����� */ static test_app_val_t g_test_app_val; @@ -140,7 +140,7 @@ static void show_hierarchical_layer_stat(void) static int update_hierarchical_layer_stat(const struct hierarchical_layer *stream_hierarchical_layer_stat) { - if(search_g_hierarchical_layer_stat(stream_hierarchical_layer_stat) == 0){ //不存�? �?新的流结�? + if(search_g_hierarchical_layer_stat(stream_hierarchical_layer_stat) == 0){ //不存?? ??新的流结?? memcpy(&g_hierarchical_layer_stat[hierarchical_layer_stat_num], stream_hierarchical_layer_stat, sizeof(struct hierarchical_layer) * MAX_LAYER_DEPTH); hierarchical_layer_stat_num++; show_hierarchical_layer_stat(); @@ -209,7 +209,7 @@ void phony_protocol_get_plugid(unsigned short plugid) phony_protocol_plugid= plugid; } -/* ģ�������, �������ļ�PLUGNAME=xxxʶ�� */ +/* ģ������?, �������ļ�PLUGNAME=xxxʶ�� */ char phony_protocol_test(struct streaminfo *a_tcp, void **pme, int thread_seq,void *a_packet) { stSessionInfo stinfo; @@ -449,6 +449,23 @@ char test_get_stream_tcp_opts(struct streaminfo *a_tcp, void **pme, int thread_ DPRINT("MESA_get_stream_opt() MSO_TCP_SYNACK_OPT error!\n"); } + uint16_t latency = 0; + int optlen = sizeof(uint16_t); + ret = MESA_get_stream_opt(a_tcp, MSO_ACCESS_LATENCY, &latency, &optlen); + if(ret >= 0){ + DPRINT("stream:%s, access latency:%ums\n", printaddr(&a_tcp->addr, thread_seq), latency); + }else{ + DPRINT("MESA_get_stream_opt() MSO_ACCESS_LATENCY error!\n"); + } + + latency = 0; + ret = MESA_get_stream_opt(a_tcp, MSO_INTERNET_LATENCY, &latency, &optlen); + if(ret >= 0){ + DPRINT("stream:%s, internet latency:%ums\n", printaddr(&a_tcp->addr, thread_seq), latency); + }else{ + DPRINT("MESA_get_stream_opt() MSO_INTERNET_LATENCY error!\n"); + } + return APP_STATE_DROPME; } @@ -466,7 +483,7 @@ char test_set_stream_timeout(struct streaminfo *pstream, void **pme, int thread ������nc����3��udp����, �˿ڷֱ�Ϊ11111, 22222, 33333, ��11s֮��, 11111Ӧ�ý���, 22s֮��, 22222Ӧ�ý���, - 33333����Ĭ��ȫ�ֳ�ʱ��̭ʱ��, �������ȫ�ֳ�ʱ��̭, Ӧ�ò������(dumpfileģʽ����). + 33333����Ĭ��ȫ�ֳ�ʱ��̭ʱ��, �������ȫ�ֳ�ʱ��?, Ӧ�ò�����?(dumpfileģʽ����). */ if((pstream->addr.tuple4_v4->source == ntohs(11111)) || (pstream->addr.tuple4_v4->dest == ntohs(11111))){ @@ -1113,7 +1130,7 @@ char test_deadlock(struct streaminfo *pstream,void **pme, int thread_seq,void *a } -/* 关于网络相关字�??, 均为网络�? network order */ +/* 关于网络相关字�??, 均为网络?? network order */ struct __test_inline_vxlan_hdr{ unsigned char flags; @@ -1121,12 +1138,12 @@ struct __test_inline_vxlan_hdr{ #if 0 unsigned char reserved[3]; #else - unsigned char nat_type; /* 复用�?�?保留字�?? 表示NAT类型 */ + unsigned char nat_type; /* 复用????保留字�?? 表示NAT类型 */ unsigned char reserved[2]; #endif /*--------int delim -------*/ unsigned char vlan_id_half_high; - unsigned char link_layer_type : 4; /* 二层报文封�?�格�? */ + unsigned char link_layer_type : 4; /* 二层报文封�?�格?? */ unsigned char vlan_id_half_low : 4; unsigned int dir : 1; unsigned int link_id : 6; @@ -1807,7 +1824,7 @@ static void test_inject_tcp_pkt_with_this_hdr(struct streaminfo *stream,void **p raw_thdr = (struct mesa_tcp_hdr *)((char *)raw_ihdr + raw_ihdr->ip_hl*4); raw_tcp_payload_len = ntohs(raw_ihdr->ip_len) - raw_ihdr->ip_hl*4 - raw_thdr->th_off * 4; - /* 当前包是C2S方向的GET, �?要回复一�?虚假的S2C方向的RESPONSE */ + /* 当前包是C2S方向的GET, ??要回复一??虚假的S2C方向的RESPONSE */ send_ihdr = (struct mesa_ip4_hdr *)pkt_header_payload; send_thdr = (struct mesa_tcp_hdr *)((char *)send_ihdr + sizeof(struct mesa_ip4_hdr)); @@ -1911,7 +1928,7 @@ char test_inject_tcp_pkt2(struct streaminfo *stream,void **pme, int thread_seq,c -/* ʹ���µķ����ӿ� sapp_inject_pkt()����α��� */ +/* ʹ���µķ����ӿ� sapp_inject_pkt()����α��? */ static int send_by_sapp_inject_pkt(struct streaminfo *a_tcp, const struct mesa_ip4_hdr *raw_ip4hdr) { #define HIJACK_RESPONSE_HDR "HTTP/1.1 200 OK\r\nServer: hijack.com\r\nContent-Length:%d\r\nContent-Type: text/html; charset=UTF-8\r\nConnection: close\r\n\r\n" @@ -1977,7 +1994,7 @@ char MESA_inject_pkt_for_l2_l3_tcp(struct streaminfo *stream,void **pme, int thr if(DIR_C2S == stream->curdir){ if(memmem(stream->ptcpdetail->pdata, stream->ptcpdetail->datalen, modify_raw_data_c2s, strlen(modify_raw_data_c2s)) != NULL){ - //������һ��get����, ������һ�����Ӧ�� + //������һ��get����, ������һ�����Ӧ�? ret = MESA_inject_pkt(stream, modify_inject_data_s2c, 1460, raw_pkt, stream->routedir ^ 1); if(ret < 0){ DPRINT("%s, MESA_inject_pkt S2C error!\n", printaddr(&stream->addr, thread_seq)); @@ -1991,7 +2008,7 @@ char MESA_inject_pkt_for_l2_l3_tcp(struct streaminfo *stream,void **pme, int thr } }else{ if(memmem(stream->ptcpdetail->pdata, stream->ptcpdetail->datalen, "
******", strlen("
******")) != NULL){
-			/* ��һ��S2CӦ����Ѿ���α�췢��, �˴�����Ҫ */
+			/* ��һ��S2CӦ����Ѿ���α�췢�?, �˴�����Ҫ */
 			ret_flag = APP_STATE_DROPPKT;
 			return APP_STATE_DROPME | ret_flag;
 		}
@@ -2015,12 +2032,12 @@ char MESA_inject_pkt_for_l2_l3_tcpall(struct streaminfo *stream,void **pme, int
 
 	if((DIR_C2S == stream->curdir) 
 	 && (stream->ptcpdetail->serverpktnum == 2)
-	 && (stream->ptcpdetail->datalen == 0)){ /* ֻ���������ָո���ɺ�, �յ�ACK������һ��get����,������ŶԲ��� */
+	 && (stream->ptcpdetail->datalen == 0)){ /* ֻ���������ָո���ɺ?, �յ�ACK������һ��get����,������ŶԲ��? */
 		inet_ntop(AF_INET, &stream->addr.tuple4_v4->daddr, server_ip, 32);
 
 		DSPRINT(raw_data_c2s, modify_inject_data_c2s, server_ip);
 		if(strlen(raw_data_c2s) != 197){
-			DPRINT("MESA_inject_pkt_for_l2_l3_tcpall(), C2S inject len is not 197, %d\n", (int)strlen(raw_data_c2s)); //Ҫ���DZ������������һ��, ������SEQ���ܲ���
+			DPRINT("MESA_inject_pkt_for_l2_l3_tcpall(), C2S inject len is not 197, %d\n", (int)strlen(raw_data_c2s)); //Ҫ���DZ������������һ�?, ������SEQ���ܲ���
 			return APP_STATE_DROPME;
 		}		
 		ret = MESA_inject_pkt(stream, raw_data_c2s, strlen(raw_data_c2s), raw_pkt, stream->routedir);
@@ -2836,19 +2853,19 @@ char TEST_TCP_LOST(struct streaminfo *a_tcp,  void **pme, int thread_seq,void *a
 		ipv4_hdr = (const struct mesa_ip4_hdr *)a_packet;
 		tcp_hdr = (const struct mesa_tcp_hdr *)((char *)ipv4_hdr + ipv4_hdr->ip_hl * 4);
 		pkt_raw_data = (char *)tcp_hdr + tcp_hdr->th_off * 4; /* ���ݰ�ԭʼ����ָ�� */
-		/* �����ش�׷�����ݵ�ԭ��, ƽ̨�����������a_tcp->ptcpdetail->pdata����һ������pkt_raw_data, �������ƫ���� */
+		/* �����ش�׷�����ݵ�ԭ��, ƽ̨�����������a_tcp->ptcpdetail->pdata����һ������pkt_raw_data, �������ƫ���? */
 		actual_data_seq = ntohl(tcp_hdr->th_seq) + ((char *)a_tcp->ptcpdetail->pdata - pkt_raw_data);
 
 		DPRINT("stream:%s, dir:%d, pkt-seq:%u, actual-data-seq:%u\n", printaddr(&a_tcp->addr, a_tcp->threadnum),a_tcp->curdir, ntohl(tcp_hdr->th_seq),  actual_data_seq);
 		
 		if(DIR_C2S == a_tcp->curdir){
-			/* ����ʵ����� == ���ϴμ���ó�������Ӧ�õ������ + ���μ���ó��Ķ������� */
+			/* ����ʵ����? == ���ϴμ���ó�������Ӧ�õ������ + ���μ���ó��Ķ������? */
 			if(actual_data_seq != tcp_status->seq_next_c2s + a_tcp->ptcpdetail->lostlen){
 				DPRINT("\033[41mstream:%s,  seq check fail!\033[0m\n", printaddr(&a_tcp->addr, a_tcp->threadnum));
 				//assert(0);
 				goto err_exit;
 			}
-			/* ��һ���ڴ��������: ��ǰʵ����� + ʵ�����ݳ��� */
+			/* ��һ���ڴ�������?: ��ǰʵ����? + ʵ�����ݳ��� */
 			tcp_status->seq_next_c2s = actual_data_seq + a_tcp->ptcpdetail->datalen;
 		}else{
 			if(actual_data_seq  != tcp_status->seq_next_s2c + a_tcp->ptcpdetail->lostlen){
@@ -2856,7 +2873,7 @@ char TEST_TCP_LOST(struct streaminfo *a_tcp,  void **pme, int thread_seq,void *a
 				//assert(0);
 				goto err_exit;
 			}
-			/* ��һ���ڴ��������: ��ǰʵ����� + ʵ�����ݳ��� */
+			/* ��һ���ڴ�������?: ��ǰʵ����? + ʵ�����ݳ��� */
 			tcp_status->seq_next_s2c = actual_data_seq + a_tcp->ptcpdetail->datalen;
 		}
 	}
@@ -3154,7 +3171,7 @@ char TEST_STREAM(struct streaminfo *stream,  void **pme, int thread_seq, const v
 		return APP_STATE_GIVEME;
 	}
 
-	/* ���д�㶫��, �ķ�CPU */
+	/* ���д�㶫�?, �ķ�CPU */
 	if(datalen > 0){
 		for(i = 0; i < datalen; i++){
 			result1[i] = (long)memchr(local_data, data[i], min_num);
@@ -3374,7 +3391,7 @@ char POLLING_ENTRY(struct streaminfo *stream,  void **pme, int thread_seq,void *
 extern long long sapp_random(void);
 char fake_deadlock(struct streaminfo *pstream,void **pme, int thread_seq,void *a_packet)
 {
-	/* ����������߳�, ģ������ */
+	/* ����������߳?, ģ������ */
 	int opt_val_len = sizeof(int);
 	int tid;
 	int tot_thread_cnt;
-- 
cgit v1.2.3