summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--benchmark_pcap/tcp/tcp_tfo.pcapbin0 -> 2371 bytes
-rw-r--r--module_test/src/gtest_main.cpp6
-rw-r--r--module_test/src/gtest_sapp_fun.h2
-rw-r--r--module_test/src/gtest_sapp_tcp.cpp12
-rw-r--r--module_test/src/gtest_sapp_tcp_plug.cpp76
-rw-r--r--src/dealpkt/deal_tcp.c48
6 files changed, 142 insertions, 2 deletions
diff --git a/benchmark_pcap/tcp/tcp_tfo.pcap b/benchmark_pcap/tcp/tcp_tfo.pcap
new file mode 100644
index 0000000..cd96bc5
--- /dev/null
+++ b/benchmark_pcap/tcp/tcp_tfo.pcap
Binary files differ
diff --git a/module_test/src/gtest_main.cpp b/module_test/src/gtest_main.cpp
index 8a4ff00..913e1ef 100644
--- a/module_test/src/gtest_main.cpp
+++ b/module_test/src/gtest_main.cpp
@@ -571,6 +571,12 @@ TEST(tcp, gtp_without_seq_and_ext)
ASSERT_EQ(GTEST_SAPP_SUCC, gtest_get_libsapp_devel_result());
}
+#define tcp_tfo 1
+TEST(tcp, tfo)
+{
+ tcp_tfo_run();
+ ASSERT_EQ(GTEST_SAPP_SUCC, gtest_get_libsapp_devel_result());
+}
/*************************** TCPALL simple Test ********************************/
#define _tcpall_offload_givestate_entry 1 // for SI symbol view
diff --git a/module_test/src/gtest_sapp_fun.h b/module_test/src/gtest_sapp_fun.h
index bb2e2ad..7d4bab7 100644
--- a/module_test/src/gtest_sapp_fun.h
+++ b/module_test/src/gtest_sapp_fun.h
@@ -240,7 +240,7 @@ void tcpall_tuple4_reuse_with_fin_run(void);
void tcp_tuple4_reuse_no_close_run(void);
void tcp_overlap_run(void);
void tcp_retransmit_run(void);
-
+void tcp_tfo_run(void);
void MESA_rst_tcp_test_v4_run(void);
void MESA_kill_tcp_test_v4_run(void);
diff --git a/module_test/src/gtest_sapp_tcp.cpp b/module_test/src/gtest_sapp_tcp.cpp
index 4fea257..b58f8ce 100644
--- a/module_test/src/gtest_sapp_tcp.cpp
+++ b/module_test/src/gtest_sapp_tcp.cpp
@@ -858,3 +858,15 @@ void tcp_offload_givestate_and_giveme_entry_run(void)
call_libsapp_devel_for_dumpfile_topspeed();
}
+
+void tcp_tfo_run(void)
+{
+ set_default_config();
+ update_plugin_inf("TCP", "tcp_tfo_entry");
+ append_plugin_inf("TCP_ALL", "tcpall_tfo_entry");
+
+ set_pcap_dumpfile("tcp/tcp_tfo.pcap");
+ ASSERT_EQ(file_md5_checksum("dumpfile", "4a62aa446bbe758c119276f4fba7d1ad"),0);
+
+ call_libsapp_devel_for_dumpfile_topspeed();
+}
diff --git a/module_test/src/gtest_sapp_tcp_plug.cpp b/module_test/src/gtest_sapp_tcp_plug.cpp
index 9b23de4..96d4555 100644
--- a/module_test/src/gtest_sapp_tcp_plug.cpp
+++ b/module_test/src/gtest_sapp_tcp_plug.cpp
@@ -1,5 +1,7 @@
#ifndef __USE_BSD
#define __USE_BSD
+#include <cstddef>
+#include <stream_inc/stream_base.h>
#endif
#ifndef __FAVOR_BSD
#define __FAVOR_BSD
@@ -2521,3 +2523,77 @@ extern "C" char tcp_offload_2st_giveme_entry(struct streaminfo *pstream,void **p
return APP_STATE_GIVEME;
}
+extern "C" char tcp_tfo_entry(struct streaminfo *pstream, void **pme,
+ int thread_seq, void *a_packet) {
+ const char fir_pkt_payload[] = {0x16, 0x03, 0x01, 0x02, 0x00, 0x01};
+ if (OP_STATE_CLOSE == pstream->opstate) {
+ if (gtest_tcp_stat.C2S_data_pkt == 3
+ && gtest_tcp_stat.C2S_data_byte == 727
+ && gtest_tcp_stat.S2C_data_pkt == 2
+ && gtest_tcp_stat.S2C_data_byte == 646) {
+ fprintf(stderr, "\033[32m tcp_tfo_entry() test succ!\033[0m\n");
+ sendto_test_result(GTEST_SAPP_SUCC);
+ } else {
+ fprintf(stderr, "\033[1;31;40m tcp_tfo_entry() test error! \
+ c2s_data_pkt is:%u, expect:%d, c2s_data_bytes:%llu, expect:%d,\
+ s2c_data_pkt is:%u, expect:%d, s2c_data_bytes:%llu, expect:%d \033[0m\n",
+ gtest_tcp_stat.C2S_data_pkt, 3,
+ gtest_tcp_stat.C2S_data_byte,727,
+ gtest_tcp_stat.S2C_data_pkt, 2,
+ gtest_tcp_stat.S2C_data_byte, 646);
+ sendto_test_result(GTEST_SAPP_ERR);
+ }
+ }else{
+ if (DIR_C2S == pstream->curdir) {
+ gtest_tcp_stat.C2S_data_pkt++;
+ gtest_tcp_stat.C2S_data_byte += pstream->ptcpdetail->datalen;
+ } else {
+ gtest_tcp_stat.S2C_data_pkt++;
+ gtest_tcp_stat.S2C_data_byte += pstream->ptcpdetail->datalen;
+ }
+ if(DIR_C2S == pstream->curdir
+ && 1 == gtest_tcp_stat.C2S_data_pkt){
+ if(pstream->ptcpdetail->pdata != NULL
+ && memcmp(pstream->ptcpdetail->pdata, fir_pkt_payload, sizeof(fir_pkt_payload)) != 0){
+ fprintf(stderr, "\033[1;31;40mtcp_tfo_entry() check first pkt payload error!\033[0m\n");
+ sendto_test_result(GTEST_SAPP_ERR);
+ return APP_STATE_DROPME;
+ }
+ }
+ }
+
+ return APP_STATE_GIVEME;
+}
+
+extern "C" char tcpall_tfo_entry(struct streaminfo *pstream, void **pme,
+ int thread_seq, void *a_packet) {
+
+ if (OP_STATE_CLOSE == pstream->pktstate) {
+ if (gtest_tcpall_stat.C2S_all_pkt == 6
+ && gtest_tcpall_stat.C2S_all_byte == 727
+ && gtest_tcpall_stat.S2C_all_pkt == 5
+ && gtest_tcpall_stat.S2C_all_byte == 646) {
+ fprintf(stderr, "\033[32m tcpall_tfo_entry() test succ!\033[0m\n");
+ sendto_test_result(GTEST_SAPP_SUCC);
+ } else {
+ fprintf(stderr, "\033[1;31;40m tcpall_tfo_entry() test error! \
+ c2s_data_pkt is:%u, expect:%d, c2s_data_bytes:%llu, expect:%d,\
+ s2c_data_pkt is:%u, expect:%d, s2c_data_bytes:%llu, expect:%d \033[0m\n",
+ gtest_tcpall_stat.C2S_all_pkt, 6,
+ gtest_tcpall_stat.C2S_all_byte,727,
+ gtest_tcpall_stat.S2C_all_pkt, 5,
+ gtest_tcpall_stat.S2C_all_byte, 646);
+ sendto_test_result(GTEST_SAPP_ERR);
+ }
+ }else{
+ if (DIR_C2S == pstream->curdir) {
+ gtest_tcpall_stat.C2S_all_pkt++;
+ gtest_tcpall_stat.C2S_all_byte += pstream->ptcpdetail->datalen;
+ } else {
+ gtest_tcpall_stat.S2C_all_pkt++;
+ gtest_tcpall_stat.S2C_all_byte += pstream->ptcpdetail->datalen;
+ }
+ }
+
+ return APP_STATE_GIVEME;
+} \ No newline at end of file
diff --git a/src/dealpkt/deal_tcp.c b/src/dealpkt/deal_tcp.c
index e855faf..1d6f3ec 100644
--- a/src/dealpkt/deal_tcp.c
+++ b/src/dealpkt/deal_tcp.c
@@ -1206,7 +1206,7 @@ static void tcp_change_stream_todata(struct streamindex *pindex,struct mesa_tcp_
pdetail_pr->link_state=STREAM_LINK_DATA;
pdetail_pr->tcpstateflag=TCP_ESTABLISHED;
- pstream->opstate=OP_STATE_PENDING;
+ // pstream->opstate=OP_STATE_PENDING; //for TFO , can't set to PENDING state
if(pstream->dir & DIR_C2S)
{
@@ -2852,6 +2852,49 @@ static int deal_tcp_stream_dup_pkt_check(int tid, struct streaminfo_private *pst
return is_dup_pkt;
}
+static int deal_tcp_tfo(struct streaminfo *pstream, const void *this_iphdr, struct mesa_tcp_hdr *this_tcphdr, int tcplen,const raw_pkt_t *raw_pkt)
+{
+ struct half_tcpstream *snd=NULL,*rcv=NULL;
+ int ret=PASS;
+ struct tcpdetail_private*pdetail_pr=(struct tcpdetail_private*)pstream->pdetail;
+ struct tcpdetail *pdetail=(struct tcpdetail *)&pdetail_pr->tcpdetail_public;
+ unsigned int this_tfo_first_seq = ntohl (this_tcphdr->th_seq) + 1; //for TFO: first_payload.seq == SYN.seq, plus 1 otherwise will be treat as overlap
+ if(pstream->curdir == DIR_C2S)
+ {
+ if(NULL == pdetail_pr->pserver){
+ pdetail_pr->pserver=(struct half_tcpstream *)sapp_mem_malloc(SAPP_MEM_DYN_TCP_HALF_STREAM,pstream->threadnum,sizeof(struct half_tcpstream));
+ memset(pdetail_pr->pserver,0,sizeof(struct half_tcpstream));
+ //������
+ pdetail_pr->pserver->first_data_seq=pdetail_pr->iserverseq;
+ /* pdetail_pr->iserverseq=0; */ /* 2016-04-27 lijia modify, ���ڻ�ȡ��ǰ����ISN */
+
+ /* 2014-10-20 LiJia add, for set one stream unorder number */
+ pdetail_pr->pserver->maxunorder = tcp_default_unorder;
+ }
+ rcv=pdetail_pr->pserver;
+ snd=pdetail_pr->pclient;
+ }
+ else
+ {
+ if(NULL == pdetail_pr->pclient){
+ pdetail_pr->pclient=(struct half_tcpstream *)sapp_mem_malloc(SAPP_MEM_DYN_TCP_HALF_STREAM,pstream->threadnum,sizeof(struct half_tcpstream));
+ memset(pdetail_pr->pclient,0,sizeof(struct half_tcpstream));
+ //������
+ pdetail_pr->pclient->first_data_seq=pdetail_pr->iclientseq;
+ /* pdetail_pr->iclientseq=0; */ /* 2016-04-27 lijia modify, ���ڻ�ȡ��ǰ����ISN */
+
+ /* 2014-10-20 LiJia add, for set one stream unorder number */
+ pdetail_pr->pclient->maxunorder = tcp_default_unorder;
+ }
+ rcv=pdetail_pr->pclient;
+ snd=pdetail_pr->pserver;
+ }
+
+ tcp_set_new_data(pstream,rcv,snd,(char *)this_tcphdr + this_tcphdr->th_off*4,tcplen,this_tfo_first_seq,this_tcphdr->th_flags & TH_FIN, raw_pkt->is_ctrl_pkt);
+ ret = stream_process_tcp(pstream, this_iphdr, this_tcphdr, raw_pkt, &(pdetail_pr->apme),&(pstream->opstate));
+ return ret;
+}
+
/* LiJia comment: pstreamָ��ջ����ڴ� */
//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,
@@ -2901,6 +2944,9 @@ static int deal_tcp_stream(struct streamindex *pindex, const void *this_iphdr, s
ret = PASS;
}else{
ret=tcp_processallpkt(pstream,this_iphdr,this_tcphdr,tcplen,raw_pkt);
+ if((PASS == ret) && (tcplen > 0)){ // for TFO
+ ret = deal_tcp_tfo(pstream, this_iphdr, this_tcphdr, tcplen, raw_pkt);
+ }
}
}
return ret;