summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author杨威 <[email protected]>2019-01-24 20:51:33 +0800
committer杨威 <[email protected]>2019-01-24 20:51:33 +0800
commit43622954ffc3036c28bcfacf539ac76e24aabaef (patch)
tree56919b41ed79c9274ca5551241167e7b7fe18694
parentb54a04f5f92b1daa9e448e910adb1977382db6c9 (diff)
parent730eea98d54e88b55a0346876ab7631598b59054 (diff)
Merge branch 'Feature-parallel-using-clock-get-time' into 'pangu_develop_parallel'
Feature parallel using clock get time See merge request MESA_Platform/sapp!1
-rw-r--r--CMakeLists.txt48
-rw-r--r--Makefile561
-rw-r--r--dealpkt/net_common.c4
-rw-r--r--dealpkt/plug_support.c1815
-rw-r--r--dealpkt/stream_manage.c7
-rw-r--r--entry/CMakeLists.txt21
-rw-r--r--entry/Makefile172
-rw-r--r--entry/sapp_init.c2
-rw-r--r--include/stream_inc/stream_base.h1059
-rw-r--r--include/stream_internal.h709
-rw-r--r--inner_plug/sapp_assistant.cpp20
-rw-r--r--makefile-cmake (renamed from cmake-makefile)0
-rw-r--r--packet_io/packet_io.c2643
-rw-r--r--packet_io/packet_io_status.cpp2
-rw-r--r--rmake2
-rw-r--r--run/conf/main.conf4
-rw-r--r--run/platform_lib/packet_io_pcap.sobin61888 -> 69800 bytes
-rw-r--r--run/plug/business/conflist_business.inf2
-rw-r--r--run/plug/business/g_device_plug/g_device_plug.sobin23304 -> 36256 bytes
-rw-r--r--run/plug/business/test_app/test_app_sapp.sobin89312 -> 92528 bytes
-rw-r--r--run/plug/business/test_app/trace_delay.sobin28064 -> 31224 bytes
-rw-r--r--run/plug/protocol/isakmp_protocol_plug/isakmp_protocol_plug.sobin22640 -> 29808 bytes
-rw-r--r--run/plug/protocol/l2tp_protocol_plug/l2tp_protocol_plug.sobin32952 -> 39232 bytes
-rw-r--r--run/plug/protocol/pptp_protocol_plug/pptp_protocol_plug.sobin32960 -> 40776 bytes
-rw-r--r--support/avl_tree/avltree.c1408
-rw-r--r--support/dictator2/src/CMakeLists.txt2
26 files changed, 4297 insertions, 4184 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5f0c16c..97e30aa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,6 +6,11 @@ include(Version)
set(CMAKE_MACOSX_RPATH 0)
+if(CMAKE_BUILD_TYPE STREQUAL "Debug")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEBUG")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DDEBUG")
+endif()
+
#set(CMAKE_INSTALL_PREFIX /home/ceiec/sapp/)
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/run/)
@@ -96,21 +101,24 @@ endif()
# Memory Allocator
option(OPT_USE_DICTATOR "Use Dictator2 memory allocator" OFF)
-option(OPT_USE_TXMEM "Use Dictator2 for TileGX memory allocator" OFF)
+option(OPT_USE_DICTATOR_DEBUG "Use Dictator2 memory allocator" OFF)
option(OPT_USE_TCMALLOC "Use TCmalloc memory allocator" OFF)
-option(OPT_USE_TCMALLOC_MINI "Use TCmalloc memory allocator MINI" OFF)
+option(OPT_USE_TCMALLOC_MINI "Use TCmalloc memory allocator" OFF)
option(OPT_USE_JEMALLOC "Use JEmalloc memory allocator" OFF)
-if(OPT_USE_DICTATOR)
- set(MEM_POOL_DEFINITIONS -DUSE_MEM_POOL=1)
+if(OPT_USE_DICTATOR_DEBUG)
+ set(MEM_POOL_DEFINITIONS -DDICTATOR_DEBUG)
endif()
-if(OPT_USE_TCMALLOC_MINI)
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ltcmalloc_minimal")
+if(OPT_USE_DICTATOR OR OPT_USE_DICTATOR_DEBUG)
+ set(MEM_POOL_DEFINITIONS ${MEM_POOL_DEFINITIONS} -DUSE_MEM_POOL=1
+ -DUSE_MEMPOOL)
+elseif(OPT_USE_TCMALLOC_MINI)
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ltcmalloc_minimal -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free")
elseif(OPT_USE_TCMALLOC)
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ltcmalloc")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ltcmalloc -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free")
elseif(OPT_USE_JEMALLOC)
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ljemalloc")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ljemalloc -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free")
endif()
add_definitions(${CAPTURE_DEFINITIONS} ${MEM_POOL_DEFINITIONS} -D__FAVOR_BSD=1
@@ -120,6 +128,29 @@ set(SAPP_DEPEND_DYN_LIB MESA_handle_logger MESA_htable pthread MESA_field_stat2
set(CMAKE_C_FLAGS_RELEASE "-Werror")
+file(MD5 ${PROJECT_SOURCE_DIR}/include/stream_inc/stream_base.h MD5_STREAM_BASE)
+file(MD5 ${PROJECT_SOURCE_DIR}/include/stream_inc/stream_control.h MD5_STREAM_CONTROL)
+file(MD5 ${PROJECT_SOURCE_DIR}/include/stream_inc/stream_entry.h MD5_STREAM_ENTRY)
+file(MD5 ${PROJECT_SOURCE_DIR}/include/stream_inc/stream_inject.h MD5_STREAM_INJECT)
+file(MD5 ${PROJECT_SOURCE_DIR}/include/stream_inc/stream_project.h MD5_STREAM_PROJECT)
+file(MD5 ${PROJECT_SOURCE_DIR}/include/stream_inc/stream_proxy.h MD5_STREAM_PROXY)
+file(MD5 ${PROJECT_SOURCE_DIR}/include/stream_inc/stream_rawpkt.h MD5_STREAM_RAWPKT)
+file(MD5 ${PROJECT_SOURCE_DIR}/include/stream_inc/stream_tunnel.h MD5_STREAM_TUNNEL)
+
+add_definitions(${HEADER_CHECK_DEFINITIONS}
+ -DSTREAM_BASE_MD5_CHECK="${MD5_STREAM_BASE}"
+ -DSTREAM_CONTROL_MD5_CHECK="${MD5_STREAM_CONTROL}"
+ -DSTREAM_ENTRY_MD5_CHECK="${MD5_STREAM_ENTRY}"
+ -DSTREAM_INJECT_MD5_CHECK="${MD5_STREAM_INJECT}"
+ -DSTREAM_PROJECT_MD5_CHECK="${MD5_STREAM_PROJECT}"
+ -DSTREAM_PROXY_MD5_CHECK="${MD5_STREAM_PROXY}"
+ -DSTREAM_RAWPKT_MD5_CHECK="${MD5_STREAM_RAWPKT}"
+ -DSTREAM_TUNNEL_MD5_CHECK="${MD5_STREAM_TUNNEL}")
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${HEADER_CHECK_DEFINITIONS}")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${HEADER_CHECK_DEFINITIONS}")
+
+add_subdirectory(test_so)
add_subdirectory(support)
add_subdirectory(dealpkt)
add_subdirectory(packet_io)
@@ -127,7 +158,6 @@ add_subdirectory(plugin)
add_subdirectory(project)
add_subdirectory(inner_plug)
add_subdirectory(entry)
-add_subdirectory(test_so)
install(PROGRAMS ${CMAKE_BINARY_DIR}/entry/sapp DESTINATION .)
diff --git a/Makefile b/Makefile
index 7df2179..0fa5795 100644
--- a/Makefile
+++ b/Makefile
@@ -1,266 +1,295 @@
-##################### MESA Makefile Common Definition Start #################
-MESA_MAKE_VERSION=20170626
-
-#CC=gcc
-CC=g++
-CCC=g++
-CFLAGS =
-#CFLAGS = -march=native
-#CFLAGS += -D__FAVOR_BSD=1 -D__USE_BSD=1 -D_GNU_SOURCE=1 -Werror -DMESA_SAPP_PLATFORM=1
-CFLAGS += -D__FAVOR_BSD=1 -D__USE_BSD=1 -D_GNU_SOURCE=1 -DMESA_SAPP_PLATFORM=1
-LIBS= -L/opt/MESA/lib
-INC=-I./
-INC+=-I/opt/MESA/include
-OBJS=
-
-_MODE_PCAP=pcap
-_MODE_PAG=pag
-_MODE_PPF=ppf
-_MODE_PFRING=pfring
-_MODE_DPDK=dpdk
-_MODE_PAG_N95=pag_n95
-_MODE_TOPSEC=topsec
-_MODE_MARSIO=marsio
-_MODE_SMITH=smith
-_MODE_DPDK_VXLAN=dpdk_vxlan
-_MODE_PAG_MARSIO=pag_marsio
-_MODE_IPFILE=ipfile
-_MODE_CHK=0
-iomode=pcap
-
-_OPT0=0
-_OPT1=1
-_OPT2=2
-_OPT3=3
-_OPT_HIGH_PERF=high_perf
-#default level is 0
-opt=0
-_OPT_CHK=0
-
-_DEBUG_CHK=0
-_DEBUG0=0
-_DEBUG1=1
-_DEBUG2=2
-#default is 2
-debug=2
-
-ifeq ($(debug), $(_DEBUG0))
-#do nothing
-_DEBUG_CHK=1
-endif
-
-ifeq ($(debug), $(_DEBUG1))
-CFLAGS += -g
-_DEBUG_CHK=1
-#do nothing
-endif
-ifeq ($(debug), $(_DEBUG2))
-CFLAGS += -g -DDEBUG=1
-_DEBUG_CHK=1
-endif
-
-ifneq ($(_DEBUG_CHK), 0)
-else
- ifeq ($(debug), 0)
- #
- else
- $(error args debug error)
- exit
- endif
-endif
-
-ifeq ($(iomode), $(_MODE_PCAP))
-_MODE_CHK=1
-LIBS += -lpcap
-endif
-ifeq ($(iomode), $(_MODE_PAG))
-LIBS += -lpag -lpthread
-_MODE_CHK=1
-endif
-ifeq ($(iomode), $(_MODE_PPF))
-LIBS += -lppf
-_MODE_CHK=1
-endif
-ifeq ($(iomode), $(_MODE_PFRING))
-LIBS += -lpfring
-_MODE_CHK=1
-endif
-
-ifeq ($(iomode), $(_MODE_DPDK))
-LIBS += -lmarsio
-_MODE_CHK=1
-endif
-
-ifeq ($(iomode), $(_MODE_TOPSEC))
-_MODE_CHK=1
-endif
-
-ifeq ($(iomode), $(_MODE_MARSIO))
-LIBS += -lmarsio
-_MODE_CHK=1
-endif
-
-ifeq ($(iomode), $(_MODE_SMITH))
-LIBS += -lagent_smith
-_MODE_CHK=1
-endif
-
-ifeq ($(iomode), $(_MODE_DPDK_VXLAN))
-LIBS += -lmarsio
-_MODE_CHK=1
-endif
-
-ifeq ($(iomode), $(_MODE_PAG_MARSIO))
-LIBS += -lpag
-_MODE_CHK=1
-endif
-
-ifeq ($(iomode), $(_MODE_IPFILE))
-_MODE_CHK=1
-endif
-
-ifneq ($(_MODE_CHK), 0)
-else
- ifeq ($(iomode), "pcap")
- else
- $(error args iomode error)
- exit
- endif
-endif
-
-ifeq ($(opt), $(_OPT0))
-opt=0
-CFLAGS += -O0
-_OPT_CHK=1
-endif
-ifeq ($(opt), $(_OPT1))
-opt=1
-CFLAGS += -O1
-_OPT_CHK=1
-endif
-ifeq ($(opt), $(_OPT2))
-opt=2
-CFLAGS += -O2
-_OPT_CHK=1
-endif
-ifeq ($(opt), $(_OPT3))
-opt=3
-CFLAGS += -O3
-_OPT_CHK=1
-endif
-ifeq ($(opt), $(_OPT_HIGH_PERF))
-opt=2
-CFLAGS += -O2 -DHIGH_PERF=1 -UDEBUG -march=native
-_OPT_CHK=1
-endif
-
-ifneq ($(_OPT_CHK), 0)
-else
- ifeq ($(opt), 0)
- #
- else
- $(error args opt error)
- exit
- endif
-endif
-
-.PHONY:help clean target
-
-export CC
-export CCC
-export CFLAGS
-export LIBS
-export INC
-export iomode
-export debug
-export _OPT_HIGH_PERF
-export _DEBUG0
-export _DEBUG1
-export _DEBUG2
-export _MODE_PCAP
-export _MODE_PAG
-export _MODE_PPF
-export _MODE_PFRING
-export _MODE_DPDK
-export _MODE_TOPSEC
-export _MODE_MARSIO
-export _MODE_SMITH
-export _MODE_DPDK_VXLAN
-export _MODE_IPFILE
-export _MODE_PAG_MARSIO
-
-target:all
-
-version:
- @echo -e "MESA Makefile version:\033[31;49;1m $(MESA_MAKE_VERSION)\033[0m"
-
-help:
- @echo -e "MESA Makefile version:\033[31;49;1m $(MESA_MAKE_VERSION)\033[0m"
- @echo "MESA-Makefile usage:"
- @echo -e "\treserved args:"
- @echo -e "\t\t\033[31;49;1m debug={0,1,2},0:release version; 1:-g; 2:-g -DDEBUG, default is 2.\033[0m"
- @echo -e "\t\t\033[31;49;1m opt={0,1,2,3,high_perf}, optimize level, default is 0.\033[0m"
- @echo -e "\t\t\033[31;49;1m iomode={pcap,ppf,pag,prfing,dpdk,tilera,topsec,ipfile,marsio,smith,dpdk_vxlan,pag_marsio}, default is pcap.\033[0m"
-
-##################### MESA Makefile Common Definition End ####################
-
-YES=1
-NO=0
-USE_MEM_POOL=$(YES)
-#USE_MEM_POOL=$(NO)
-USE_PAG_GET_FRAME=$(YES)
-#USE_PAG_GET_FRAME=$(NO)
-INSTALL_PATH=./run
-
-export USE_MEM_POOL
-export USE_PAG_GET_FRAME
-export YES
-export NO
-
-all:
- cd support/avl_tree; $(MAKE);
- cd support/MESA_sleep; $(MAKE);
- cd support/dictator2/src; $(MAKE);
- cd support/md5; $(MAKE);
- cd support/rb_tree; $(MAKE);
- cd support/symbol_check; $(MAKE);
- cd support/timestamp_record; $(MAKE);
- cd support/iknow; $(MAKE);
- cd support/MESA_socket_wrap; $(MAKE);
- cd support/c3_client; $(MAKE);
- cd dealpkt; $(MAKE);
- cd packet_io; $(MAKE);
- cd project; $(MAKE);
- cd plugin; $(MAKE);
- cd inner_plug; $(MAKE);
- cd entry; $(MAKE);
- nm run/sapp | grep version_VERSION;
-
-clean:
- rm -rf build/*;
- rm -f run/sapp;
- rm -f lib/*.a;
- cd test_so; $(MAKE) clean;
- cd dealpkt; $(MAKE) clean;
- cd packet_io; $(MAKE) clean;
- cd project; $(MAKE) clean;
- cd plugin; $(MAKE) clean;
- cd inner_plug; $(MAKE) clean;
- cd entry; $(MAKE) clean;
- cd support/c3_client; $(MAKE) clean;
- cd support/dictator2/src; $(MAKE) clean;
- cd support/MESA_sleep; $(MAKE) clean;
- cd support/md5; $(MAKE) clean;
- cd support/rb_tree; $(MAKE) clean;
- cd support/symbol_check; $(MAKE) clean;
- cd support/timestamp_record; $(MAKE) clean;
- cd support/iknow; $(MAKE) clean;
- cd support/MESA_socket_wrap; $(MAKE) clean;
- cd support/avl_tree; $(MAKE) clean;
-
-install:
- mkdir -p /opt/MESA/include;
- mkdir -p /opt/MESA/lib;
- cp -r -f include/support/pcap* /opt/MESA/include
- ln -sf /usr/lib64/libpcap.so.1 /opt/MESA/lib/libpcap.so;
- cp packet_io/*.so $(INSTALL_PATH)/platform_lib/
+##################### MESA Makefile Common Definition Start #################
+MESA_MAKE_VERSION=20170626
+
+#CC=gcc
+CC=g++
+CCC=g++
+CFLAGS =
+#CFLAGS = -march=native
+#CFLAGS += -D__FAVOR_BSD=1 -D__USE_BSD=1 -D_GNU_SOURCE=1 -Werror -DMESA_SAPP_PLATFORM=1
+CFLAGS += -D__FAVOR_BSD=1 -D__USE_BSD=1 -D_GNU_SOURCE=1 -DMESA_SAPP_PLATFORM=1
+LIBS= -L/opt/MESA/lib
+INC=-I./
+INC+=-I/opt/MESA/include
+OBJS=
+
+_MODE_PCAP=pcap
+_MODE_PAG=pag
+_MODE_PPF=ppf
+_MODE_PFRING=pfring
+_MODE_DPDK=dpdk
+_MODE_PAG_N95=pag_n95
+_MODE_TOPSEC=topsec
+_MODE_MARSIO=marsio
+_MODE_SMITH=smith
+_MODE_DPDK_VXLAN=dpdk_vxlan
+_MODE_PAG_MARSIO=pag_marsio
+_MODE_IPFILE=ipfile
+_MODE_CHK=0
+iomode=pcap
+
+_OPT0=0
+_OPT1=1
+_OPT2=2
+_OPT3=3
+_OPT_HIGH_PERF=high_perf
+#default level is 0
+opt=0
+_OPT_CHK=0
+
+_DEBUG_CHK=0
+_DEBUG0=0
+_DEBUG1=1
+_DEBUG2=2
+#default is 2
+debug=2
+
+ifeq ($(debug), $(_DEBUG0))
+#do nothing
+_DEBUG_CHK=1
+endif
+
+ifeq ($(debug), $(_DEBUG1))
+CFLAGS += -g
+_DEBUG_CHK=1
+#do nothing
+endif
+ifeq ($(debug), $(_DEBUG2))
+CFLAGS += -g -DDEBUG=1
+_DEBUG_CHK=1
+endif
+
+ifneq ($(_DEBUG_CHK), 0)
+else
+ ifeq ($(debug), 0)
+ #
+ else
+ $(error args debug error)
+ exit
+ endif
+endif
+
+ifeq ($(iomode), $(_MODE_PCAP))
+_MODE_CHK=1
+LIBS += -lpcap
+endif
+ifeq ($(iomode), $(_MODE_PAG))
+LIBS += -lpag -lpthread
+_MODE_CHK=1
+endif
+ifeq ($(iomode), $(_MODE_PPF))
+LIBS += -lppf
+_MODE_CHK=1
+endif
+ifeq ($(iomode), $(_MODE_PFRING))
+LIBS += -lpfring
+_MODE_CHK=1
+endif
+
+ifeq ($(iomode), $(_MODE_DPDK))
+LIBS += -lmarsio
+_MODE_CHK=1
+endif
+
+ifeq ($(iomode), $(_MODE_TOPSEC))
+_MODE_CHK=1
+endif
+
+ifeq ($(iomode), $(_MODE_MARSIO))
+LIBS += -lmarsio
+_MODE_CHK=1
+endif
+
+ifeq ($(iomode), $(_MODE_SMITH))
+LIBS += -lagent_smith
+_MODE_CHK=1
+endif
+
+ifeq ($(iomode), $(_MODE_DPDK_VXLAN))
+LIBS += -lmarsio
+_MODE_CHK=1
+endif
+
+ifeq ($(iomode), $(_MODE_PAG_MARSIO))
+LIBS += -lpag
+_MODE_CHK=1
+endif
+
+ifeq ($(iomode), $(_MODE_IPFILE))
+_MODE_CHK=1
+endif
+
+ifneq ($(_MODE_CHK), 0)
+else
+ ifeq ($(iomode), "pcap")
+ else
+ $(error args iomode error)
+ exit
+ endif
+endif
+
+ifeq ($(opt), $(_OPT0))
+opt=0
+CFLAGS += -O0
+_OPT_CHK=1
+endif
+ifeq ($(opt), $(_OPT1))
+opt=1
+CFLAGS += -O1
+_OPT_CHK=1
+endif
+ifeq ($(opt), $(_OPT2))
+opt=2
+CFLAGS += -O2
+_OPT_CHK=1
+endif
+ifeq ($(opt), $(_OPT3))
+opt=3
+CFLAGS += -O3
+_OPT_CHK=1
+endif
+ifeq ($(opt), $(_OPT_HIGH_PERF))
+opt=2
+CFLAGS += -O2 -DHIGH_PERF=1 -UDEBUG -march=native
+_OPT_CHK=1
+endif
+
+ifneq ($(_OPT_CHK), 0)
+else
+ ifeq ($(opt), 0)
+ #
+ else
+ $(error args opt error)
+ exit
+ endif
+endif
+
+.PHONY:help clean target
+
+export CC
+export CCC
+export CFLAGS
+export LIBS
+export INC
+export iomode
+export debug
+export _OPT_HIGH_PERF
+export _DEBUG0
+export _DEBUG1
+export _DEBUG2
+export _MODE_PCAP
+export _MODE_PAG
+export _MODE_PPF
+export _MODE_PFRING
+export _MODE_DPDK
+export _MODE_TOPSEC
+export _MODE_MARSIO
+export _MODE_SMITH
+export _MODE_DPDK_VXLAN
+export _MODE_IPFILE
+export _MODE_PAG_MARSIO
+
+target:all
+
+version:
+ @echo -e "MESA Makefile version:\033[31;49;1m $(MESA_MAKE_VERSION)\033[0m"
+
+help:
+ @echo -e "MESA Makefile version:\033[31;49;1m $(MESA_MAKE_VERSION)\033[0m"
+ @echo "MESA-Makefile usage:"
+ @echo -e "\treserved args:"
+ @echo -e "\t\t\033[31;49;1m debug={0,1,2},0:release version; 1:-g; 2:-g -DDEBUG, default is 2.\033[0m"
+ @echo -e "\t\t\033[31;49;1m opt={0,1,2,3,high_perf}, optimize level, default is 0.\033[0m"
+ @echo -e "\t\t\033[31;49;1m iomode={pcap,ppf,pag,prfing,dpdk,tilera,topsec,ipfile,marsio,smith,dpdk_vxlan,pag_marsio}, default is pcap.\033[0m"
+
+##################### MESA Makefile Common Definition End ####################
+
+YES=1
+NO=0
+USE_MEM_POOL=$(YES)
+#USE_MEM_POOL=$(NO)
+USE_PAG_GET_FRAME=$(YES)
+#USE_PAG_GET_FRAME=$(NO)
+INSTALL_PATH=./run
+
+#md5sum "./include/stream_inc/stream_base.h"
+
+MD5_STREAM_BASE=$(shell md5sum "./include/stream_inc/stream_base.h"|cut -d ' ' -f1)
+MD5_STREAM_ENTRY=$(shell md5sum "./include/stream_inc/stream_entry.h"|cut -d ' ' -f1)
+MD5_STREAM_CONTROL=$(shell md5sum "./include/stream_inc/stream_control.h"|cut -d ' ' -f1)
+MD5_STREAM_INJECT=$(shell md5sum "./include/stream_inc/stream_inject.h"|cut -d ' ' -f1)
+MD5_STREAM_PROJECT=$(shell md5sum "./include/stream_inc/stream_project.h"|cut -d ' ' -f1)
+MD5_STREAM_PROXY=$(shell md5sum "./include/stream_inc/stream_proxy.h"|cut -d ' ' -f1)
+MD5_STREAM_RAWPKT=$(shell md5sum "./include/stream_inc/stream_rawpkt.h"|cut -d ' ' -f1)
+MD5_STREAM_TUNNEL=$(shell md5sum "./include/stream_inc/stream_tunnel.h"|cut -d ' ' -f1)
+
+HEADER_CHECK_FLAGS += -DSTREAM_BASE_MD5_CHECK=\"$(MD5_STREAM_BASE)\"
+HEADER_CHECK_FLAGS += -DSTREAM_CONTROL_MD5_CHECK=\"$(MD5_STREAM_CONTROL)\"
+HEADER_CHECK_FLAGS += -DSTREAM_ENTRY_MD5_CHECK=\"$(MD5_STREAM_ENTRY)\"
+HEADER_CHECK_FLAGS += -DSTREAM_INJECT_MD5_CHECK=\"$(MD5_STREAM_INJECT)\"
+HEADER_CHECK_FLAGS += -DSTREAM_PROJECT_MD5_CHECK=\"$(MD5_STREAM_PROJECT)\"
+HEADER_CHECK_FLAGS += -DSTREAM_PROXY_MD5_CHECK=\"$(MD5_STREAM_PROXY)\"
+HEADER_CHECK_FLAGS += -DSTREAM_RAWPKT_MD5_CHECK=\"$(MD5_STREAM_RAWPKT)\"
+HEADER_CHECK_FLAGS += -DSTREAM_TUNNEL_MD5_CHECK=\"$(MD5_STREAM_TUNNEL)\"
+
+GIT_BRANCH=$(shell git symbolic-ref --short -q HEAD)
+GIT_SHA1=$(shell git rev-parse HEAD)
+MAKE_TIME=$(shell date "+%Y-%m-%d_%H:%M:%S")
+VERSION_FLAGS += -DGITVER=\"3.0.0-$(GIT_BRANCH)-$(GIT_SHA1)-$(MAKE_TIME)\"
+
+CFLAGS += ${HEADER_CHECK_FLAGS} ${VERSION_FLAGS}
+CXXFLAGS += ${HEADER_CHECK_FLAGS} ${VERSION_FLAGS}
+
+
+export USE_MEM_POOL
+export USE_PAG_GET_FRAME
+export YES
+export NO
+
+all:
+ cd support/avl_tree; $(MAKE);
+ cd support/MESA_sleep; $(MAKE);
+ cd support/dictator2/src; $(MAKE);
+ cd support/md5; $(MAKE);
+ cd support/rb_tree; $(MAKE);
+ cd support/symbol_check; $(MAKE);
+ cd support/timestamp_record; $(MAKE);
+ cd support/iknow; $(MAKE);
+ cd support/MESA_socket_wrap; $(MAKE);
+ cd support/c3_client; $(MAKE);
+ cd dealpkt; $(MAKE);
+ cd packet_io; $(MAKE);
+ cd project; $(MAKE);
+ cd plugin; $(MAKE);
+ cd inner_plug; $(MAKE);
+ cd entry; $(MAKE);
+ nm run/sapp | grep version_VERSION;
+
+clean:
+ rm -rf build/*;
+ rm -f run/sapp;
+ rm -f lib/*.a;
+ cd test_so; $(MAKE) clean;
+ cd dealpkt; $(MAKE) clean;
+ cd packet_io; $(MAKE) clean;
+ cd project; $(MAKE) clean;
+ cd plugin; $(MAKE) clean;
+ cd inner_plug; $(MAKE) clean;
+ cd entry; $(MAKE) clean;
+ cd support/c3_client; $(MAKE) clean;
+ cd support/dictator2/src; $(MAKE) clean;
+ cd support/MESA_sleep; $(MAKE) clean;
+ cd support/md5; $(MAKE) clean;
+ cd support/rb_tree; $(MAKE) clean;
+ cd support/symbol_check; $(MAKE) clean;
+ cd support/timestamp_record; $(MAKE) clean;
+ cd support/iknow; $(MAKE) clean;
+ cd support/MESA_socket_wrap; $(MAKE) clean;
+ cd support/avl_tree; $(MAKE) clean;
+
+install:
+ mkdir -p /opt/MESA/include;
+ mkdir -p /opt/MESA/lib;
+ cp -r -f include/support/pcap* /opt/MESA/include
+ ln -sf /usr/lib64/libpcap.so.1 /opt/MESA/lib/libpcap.so;
+ cp packet_io/*.so $(INSTALL_PATH)/platform_lib/
diff --git a/dealpkt/net_common.c b/dealpkt/net_common.c
index 0b0ac30..1648cb5 100644
--- a/dealpkt/net_common.c
+++ b/dealpkt/net_common.c
@@ -442,7 +442,9 @@ static int mpls_jump_to_layer(const char *raw_data, int raw_layer_type, int exp
}else if((*next_layer_data & 0x60) == 0x60){
skip_len = ipv6_jump_to_layer(next_layer_data, __ADDR_TYPE_IP_PAIR_V6, expect_layer_type);
}else{
- sapp_runtime_log(20, "TODO: jmp unsupport type in MPLS, 0x%x!\n", (unsigned char)(*next_layer_data));
+ //skip_len = eth_jump_to_layer(next_layer_data, ADDR_TYPE_MPLS, expect_layer_type);
+ sapp_runtime_log(20, "WARNING: jmp unsupport type in MPLS to Ethernet, 0x%x!\n", (unsigned char)
+ (*next_layer_data));
return -1;
}
diff --git a/dealpkt/plug_support.c b/dealpkt/plug_support.c
index aa51b60..24e43c3 100644
--- a/dealpkt/plug_support.c
+++ b/dealpkt/plug_support.c
@@ -1,907 +1,908 @@
-/*
- ���ļ���ƽ̨������Ҫ�Ĺ��ܺͺ���,
- ���ṩ������ҵ�����Ľӿ�, ��MESA_set_stream_opt, printaddr��,
-*/
-#include "stream_internal.h"
-#include "stream_manage.h"
-#include "sysinfo.h"
-#include "packet_io.h"
-#include "packet_io_internal.h"
-#include "project_requirement.h"
-#include "project_internal.h"
-#include "dictator.h"
-#include <MESA/MESA_handle_logger.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <assert.h>
-#include <string.h>
-#include <arpa/inet.h>
-#include <pthread.h>
-#include <sys/select.h>
-#include <linux/version.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int G_DICTATOR_SW = 1;
-extern int g_packet_io_thread_num;
-
-extern const raw_ipfrag_list_t *get_raw_frag_list(const struct streaminfo *stream);
-
-int get_opt_from_rawpkt(const void *voidpkt, int type, void *void_value)
-{
- int ret = 0;
- const raw_pkt_t *rawpkt = (const raw_pkt_t *)voidpkt;
-
- if(NULL == voidpkt || NULL == void_value){
- return -1;
- }
-
- if(RAW_PKT_MAGIC_NUM != rawpkt->magic_num){ /* ������Դ��pappƽ̨, ��֧�ִ��๦�� */
- return -1;
- }
-
- switch(type){
- case RAW_PKT_GET_DATA:
- {
- void **out_value = (void **)void_value;
- *out_value = (void *)rawpkt->raw_pkt_data;
- }
- break;
-
- case RAW_PKT_GET_RAW_PKT_TYPE:
- {
- enum addr_type_t *out_value = (enum addr_type_t *)void_value;
- *out_value = rawpkt->low_layer_type;
- }
- break;
-
- case RAW_PKT_GET_TOT_LEN:
- {
- int *out_value = (int *)void_value;
- *out_value = rawpkt->raw_pkt_len;
- }
- break;
-
- case RAW_PKT_GET_TIMESTAMP:
- {
- struct timeval *out_value =(struct timeval *)void_value;
- memcpy(out_value, &rawpkt->raw_pkt_ts, sizeof(struct timeval));
- }
- break;
-
- case RAW_PKT_GET_THIS_LAYER_HDR:
- {
- void **out_value = (void **)void_value;
- const char *this_layer_hdr = (const char *)rawpkt->raw_pkt_data + rawpkt->offset_to_raw_pkt_hdr;
- *out_value = (void *)this_layer_hdr;
- }
- break;
-
- case RAW_PKT_GET_THIS_LAYER_REMAIN_LEN:
- {
- int *out_value = (int *)void_value;
- *out_value = rawpkt->raw_pkt_len - rawpkt->offset_to_raw_pkt_hdr;
- }
- break;
-
- default:
- ret = -1;
- break;
- }
-
- return ret;
-}
-
-int get_rawpkt_opt_from_streaminfo(const struct streaminfo *pstream, int type, void *out_value)
-{
- int ret = -1;
- const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
-
- if(NULL == out_value){
- return -1;
- }
-
- if((RAW_PKT_GET_DATA == type)
- && ((PKT_TYPE_IPREBUILD & pstream->addr.pktipfragtype) != 0)){
- const raw_ipfrag_list_t *list_tmp = get_raw_frag_list(pstream);
- if(NULL == list_tmp){
- ret = -1;
- }else{
- const raw_ipfrag_list_t **out_list = (const raw_ipfrag_list_t **)out_value;
- *out_list = list_tmp;
- ret = 1;
- }
- return ret;
- }
-
- return get_opt_from_rawpkt(pstream_pr->raw_pkt, type, out_value);
-}
-
-/*Convert tuple4 to string. Format: 10.0.0.1, 1234->10.0.0.2,5678*/
-const char *printaddr (const struct layer_addr *paddrinfo,int threadindex)
-{
- static char maxbuf[64+1][128];
- char *buf=maxbuf[threadindex];
- char ip_str[64];
- struct stream_tuple4_v4 *paddr;
- struct stream_tuple4_v6 *paddr6;
-
- if(NULL == paddrinfo){
- return NULL;
- }
-
- switch(paddrinfo->addrtype){
- case ADDR_TYPE_IPV4:
- {
- paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr;
- memset(buf,0,64);
- //strcpy (buf, int_ntoa (paddr->saddr));
- inet_ntop(AF_INET, &paddr->saddr, ip_str, 64);
- strcpy (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u>", ntohs(paddr->source));
- //strcat (buf, int_ntoa (paddr->daddr));
- inet_ntop(AF_INET, &paddr->daddr, ip_str, 64);
- strcat (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u", ntohs(paddr->dest));
- }
- break;
-
- case ADDR_TYPE_IPV6:
- {
- paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr);
- memset(buf,0,128);
- inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64);
- strcpy (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u>", ntohs(paddr6->source));
- inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64);
- strcat (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u", ntohs(paddr6->dest));
- }
- break;
-
- case __ADDR_TYPE_IP_PAIR_V4:
- {
- paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr;
- memset(buf,0,128);
- //strcpy (buf, int_ntoa (paddr->saddr));
- inet_ntop(AF_INET, &paddr->saddr, ip_str, 64);
- strcpy (buf, ip_str);
- strcat (buf, ">");
- inet_ntop(AF_INET, &paddr->daddr, ip_str, 64);
- strcat (buf, ip_str);
- }
- break;
-
- case __ADDR_TYPE_IP_PAIR_V6:
- {
- paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr);
- memset(buf,0,128);
- inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64);
- strcpy (buf, ip_str);
- strcat (buf, ">");
- inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64);
- strcat (buf, ip_str);
- }
- break;
-
- default:
- {
- return (const char *)"Not support layer type";
- }
- break;
- }
-
- return buf;
-}
-
-/*
- This is a reentrant version of printaddr(),
- Convert tuple4 to string store in out_buf.
- Format: 10.0.0.1, 1234->10.0.0.2,5678.
-*/
-const char *printaddr_r(const struct layer_addr *paddrinfo, char *out_buf, int out_buf_len)
-{
-#define __MIN_ADDR_STR_LEN (20) /* ��С��ַ�ַ�������, ����:1.1.1.1.1>2.2.2.2.2 */
- char maxbuf[128];
- char *buf=maxbuf;
- char ip_str[64];
- int addr_str_len;
- struct stream_tuple4_v4 *paddr;
- struct stream_tuple4_v6 *paddr6;
-
- if((NULL == paddrinfo) || (NULL == out_buf)){
- return "invalid args";
- }
-
- if(paddrinfo->addrtype==ADDR_TYPE_IPV4)
- {
- paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr;
- memset(buf,0,128);
- //strcpy (buf, int_ntoa (paddr->saddr));
- inet_ntop(AF_INET, &paddr->saddr, ip_str, 64);
- strcpy (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u>", ntohs(paddr->source));
- //strcat (buf, int_ntoa (paddr->daddr));
- inet_ntop(AF_INET, &paddr->daddr, ip_str, 64);
- strcat (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u", ntohs(paddr->dest));
- }
- //to addjust
- else if(paddrinfo->addrtype==ADDR_TYPE_IPV6)
- {
- paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr);
- memset(buf,0,128);
- inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64);
- strcpy (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u>", ntohs(paddr6->source));
- inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64);
- strcat (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u", ntohs(paddr6->dest));
- }
- else
- {
- return (const char *)"Not support layer type";
- }
-
- addr_str_len = strlen(buf) + 1; /* add EOF */
- if(addr_str_len > out_buf_len){
- return (const char *)"buf len not enough";
- }
-
- memcpy(out_buf, buf, addr_str_len);
-
- return out_buf;
-}
-
-
-struct layer_addr * layer_addr_dup(const struct layer_addr *stack_info)
-{
- void *addr_value;
- struct layer_addr *heap_addr = (struct layer_addr *)malloc(sizeof(struct layer_addr));
- addr_value = malloc(stack_info->addrlen);
-
- memcpy(heap_addr, stack_info, sizeof(struct layer_addr));
- memcpy(addr_value, stack_info->paddr, stack_info->addrlen);
- heap_addr->paddr = addr_value;
-
- return heap_addr;
-}
-
-void layer_addr_free(struct layer_addr *paddrinfo)
-{
- free(paddrinfo->paddr);
- free(paddrinfo);
-}
-
-int get_thread_count(void)
-{
- return g_packet_io_thread_num;
-}
-
-
-int MESA_set_stream_opt(const struct streaminfo *pstream, enum MESA_stream_opt opt, void *opt_val, int opt_val_len)
-{
- int ret = -1;
-
- if((NULL == opt_val) || (opt_val_len <= 0)){
- return -1;
- }
-
- switch((int)opt){
- case (int)MSO_MAX_UNORDER:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- printf("MESA_set_stream_opt() error:stream type is not tcp!\n");
- ret = -1;
- break;
- }
- if(opt_val_len != sizeof(struct max_unorder_opt)){
- printf("MESA_set_stream_opt() error:opt_val_len invalid, must be sizeof(struct max_unorder_opt)\n");
- ret = -1;
- break;
- }
- struct max_unorder_opt *max_uorder = (struct max_unorder_opt *)opt_val;
- ret = tcp_set_single_stream_max_unorder(pstream, max_uorder->stream_dir, max_uorder->max_unorder_val);
- }
- break;
-
- case (int)MSO_NEED_ACK:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- printf("MESA_set_stream_opt() error:stream type is not tcp!\n");
- ret = -1;
- break;
- }
- unsigned char nack = *((unsigned char *)opt_val);
- struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- pdetail_pr->needackflag = nack;
- ret = 0;
- }
- break;
-
- case (int)MSO_TAKEOVER:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- printf("MESA_set_stream_opt() error:stream type is not tcp!\n");
- ret = -1;
- break;
- }
- int takeover = *((int *)opt_val);
- struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail);
- pdetail_pr->takeoverflag = takeover;
- ret = 0;
- }
- break;
-
- case (int)MSO_TIMEOUT:
- {
- if(sizeof(short) != opt_val_len){
- printf("MESA_set_stream_opt() error:opt_val_len invalid, must be sizeof(short)\n");
- ret = -1;
- break;
- }
- unsigned short tmout = *((unsigned short *)opt_val);
- ret = stream_set_single_stream_timeout(pstream, tmout);
- }
- break;
-
- case (int)MSO_IGNORE_RST_FIN:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- printf("MESA_set_stream_opt() error: stream type is not tcp!\n");
- ret = -1;
- break;
- }
- unsigned char igrstfin = *((unsigned char *)opt_val);
- struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- pdetail_pr->ignore_rst_fin = igrstfin;
- ret = 0;
- }
- break;
-
- default:
- printf("MESA_set_stream_opt() error: unsupport MESA_stream_opt type!\n");
- ret = -1;
- break;
- }
-
- return ret;
-}
-
-
-static inline int tcp_get_single_stream_max_unorder(const struct streaminfo *pstream, void *opt_val, int *opt_val_len)
-{
- struct max_unorder_opt out_val;
- struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private *)pstream->pdetail;
- UINT16 out_uorder_C2S = 0, out_uorder_S2C = 0;
-
- memset(&out_val, 0, sizeof(struct max_unorder_opt));
- if((pdetail_pr->pserver != NULL) && (tcp_default_unorder != pdetail_pr->pserver->maxunorder)){
- out_uorder_C2S = pdetail_pr->pserver->maxunorder;
- out_val.stream_dir |= DIR_C2S;
- }
-
- if((pdetail_pr->pclient != NULL) && (tcp_default_unorder != pdetail_pr->pclient->maxunorder)){
- out_uorder_S2C = pdetail_pr->pclient->maxunorder;
- out_val.stream_dir |= DIR_S2C;
- }
-
- out_val.max_unorder_val = (out_uorder_C2S > out_uorder_S2C)?out_uorder_C2S: out_uorder_S2C;
-
- memcpy(opt_val, &out_val, sizeof(struct max_unorder_opt));
-
- *opt_val_len = sizeof(struct max_unorder_opt);
-
- return 0;
-}
-
-
-static void sapp_mac_addr_to_long(const unsigned char *mac_addr, unsigned long long *smac_integer_type)
-{
- int i;
- char *ptr = (char *)smac_integer_type;
-
- ptr += 5; /* ָ��long long �ĵ�6���ֽ� */
-
- for(i = 0; i < 6; i++){
- *ptr-- = *mac_addr++; /* �������ݰ���mac�����λ, copy��long long���������λ(��ȥ���2���ֽں�) */
- }
-}
-
-static int sapp_get_vxlan_info_from_streaminfo(const struct streaminfo *pstream, struct vxlan_info *vxinfo)
-{
-#define GDEV_SMAC_MASK_ENCAP_TYPE (0x00000000000F0000)
-#define GDEV_SMAC_MASK_ENTRANCE_ID (0x0000000000007C00)
-#define GDEV_SMAC_MASK_DEV_ID (0x00000000000003F0)
-#define GDEV_SMAC_MASK_LINK_ID (0x000000000000000E)
-#define GDEV_SMAC_MASK_LINK_DIR (0x0000000000000001)
-
-
- int ret, i;
- const struct streaminfo *mim_stream = pstream->pfather;
- const struct layer_addr_mac_in_mac *mim_addr;
- const struct layer_addr_mac *mac_addr;
- unsigned char *ptr;
- unsigned long long smac_integer_type; /* 48bit macת��Ϊ64bit�ij��������ִ洢, ���ڲ��� */
-
- while(mim_stream){
- if(ADDR_TYPE_MAC_IN_MAC == mim_stream->addr.addrtype || ADDR_TYPE_MAC == mim_stream->addr.addrtype){
- break;
- }else{
- mim_stream = mim_stream->pfather;
- }
- }
-
- if(NULL == mim_stream){
- return -1;
- }
-
- memset(vxinfo, 0, sizeof(struct vxlan_info));
-
- if(ADDR_TYPE_MAC_IN_MAC == mim_stream->addr.addrtype)
- {
- mim_addr = mim_stream->addr.mimac;
- sapp_mac_addr_to_long(mim_addr->outer_src_mac, &smac_integer_type);
- }
- else
- {
- mac_addr = mim_stream->addr.mac;
- sapp_mac_addr_to_long(mac_addr->src_mac, &smac_integer_type);
- }
- vxinfo->encap_type = (smac_integer_type & GDEV_SMAC_MASK_ENCAP_TYPE) >> 16;
- vxinfo->entrance_id = (smac_integer_type & GDEV_SMAC_MASK_ENTRANCE_ID) >> 10;
- vxinfo->dev_id = (smac_integer_type & GDEV_SMAC_MASK_DEV_ID) >> 4;
- vxinfo->link_id = (smac_integer_type & GDEV_SMAC_MASK_LINK_ID ) >> 1;
- vxinfo->link_dir = (smac_integer_type & GDEV_SMAC_MASK_LINK_DIR);
-
- if(ADDR_TYPE_MAC_IN_MAC == mim_stream->addr.addrtype)
- {
- ptr = vxinfo->inner_smac;
- for(i = 0; i < 6; i++, ptr += 3){
- sprintf((char *)ptr, "%02x:", mim_addr->inner_src_mac[i]);
- }
- vxinfo->inner_smac[17] = '\0'; /* ���һλ���� */
- memcpy(vxinfo->inner_smac_hex, mim_addr->inner_src_mac, 6);
-
- ptr = vxinfo->inner_dmac;
- for(i = 0; i < 6; i++, ptr += 3){
- sprintf((char *)ptr, "%02x:", mim_addr->inner_dst_mac[i]);
- }
- vxinfo->inner_dmac[17] = '\0'; /* ���һλ���� */
- memcpy(vxinfo->inner_dmac_hex, mim_addr->inner_dst_mac, 6);
- }
- else
- {
- ptr = vxinfo->inner_smac;
- for(i = 0; i < 6; i++, ptr += 3){
- sprintf((char *)ptr, "%02x:", mac_addr->src_mac[i]);
- }
- vxinfo->inner_smac[17] = '\0'; /* ���һλ���� */
- memcpy(vxinfo->inner_smac_hex, mac_addr->src_mac, 6);
-
- ptr = vxinfo->inner_dmac;
- for(i = 0; i < 6; i++, ptr += 3){
- sprintf((char *)ptr, "%02x:", mac_addr->dst_mac[i]);
- }
- vxinfo->inner_dmac[17] = '\0'; /* ���һλ���� */
- memcpy(vxinfo->inner_dmac_hex, mac_addr->dst_mac, 6);
- }
- return 0;
-}
-
-int MESA_get_stream_opt(const struct streaminfo *pstream, enum MESA_stream_opt opt, void *opt_val, int *opt_val_len)
-{
- int ret = 0;
-
- if((NULL == opt_val) || (NULL == opt_val_len) || (*opt_val_len <= 0)){
- return -1;
- }
-
- switch((int)opt){
- case (int)MSO_MAX_UNORDER:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:stream type is not tcp!\n");
- ret = -1;
- break;
- }
- if(*opt_val_len < (int)sizeof(struct max_unorder_opt)){
- sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:opt_val_len invalid, must be sizeof(struct max_unorder_opt)\n");
- ret = -1;
- break;
- }
- *opt_val_len = sizeof(struct max_unorder_opt);
- ret = tcp_get_single_stream_max_unorder(pstream, opt_val, opt_val_len);
- }
- break;
-
- case (int)MSO_NEED_ACK:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:stream type is not tcp!\n");
- ret = -1;
- break;
- }
- unsigned char *nack = (unsigned char *)opt_val;
- struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- *nack = pdetail_pr->needackflag;
- *opt_val_len = sizeof(char);
- }
- break;
-
- case (int)MSO_TAKEOVER:
- {
- if(*opt_val_len < (int)sizeof(int)){
- ret = -1;
- break;
- }
- if(STREAM_TYPE_TCP != pstream->type){
- sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:stream type is not tcp!\n");
- ret = -1;
- break;
- }
- int *takeover = (int *)opt_val;
- struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail);
- *takeover = pdetail_pr->takeoverflag;
- *opt_val_len = sizeof(int);
- }
- break;
-
- case (int)MSO_TIMEOUT:
- {
- if(sizeof(short) != *opt_val_len){
- sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:opt_val_len invalid, must be sizeof(short)\n");
- ret = -1;
- break;
- }
- unsigned short *tmout = (unsigned short *)opt_val;
- struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream;
- *tmout = pstream_pr->timeout;
- *opt_val_len = sizeof(short);
- }
- break;
-
- case (int)MSO_IGNORE_RST_FIN:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:stream type is not tcp!\n");
- ret = -1;
- break;
- }
- unsigned char *igrstfin = (unsigned char *)opt_val;
- struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- *igrstfin = pdetail_pr->ignore_rst_fin;
- }
- break;
-
- case MSO_TCP_CREATE_LINK_MODE:
- {
- struct tcpdetail_private *pdetail_pr;
- UCHAR *out_val = (UCHAR *)opt_val;
- if(STREAM_TYPE_TCP != pstream->type){
- ret = -1;
- sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:stream type is not tcp!\n");
- break;
- }
-
- pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- *out_val = pdetail_pr->creat_mod;
- *opt_val_len = sizeof(char);
- }
- break;
-
- case MSO_TCP_ISN_C2S:
- {
- struct tcpdetail_private *pdetail_pr;
- UINT32 *out_val = (UINT32 *)opt_val;
- if(STREAM_TYPE_TCP != pstream->type){
- ret = -1;
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:stream type is not tcp!\n");
- break;
- }
-
- pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- if(pdetail_pr->creat_mod != TCP_CTEAT_LINK_BYSYN){
- ret = -1;
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error: stream create mode is not by SYN!\n");
- break;
- }
- if(0 == pdetail_pr->iserverseq){
- ret = -1;
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error: can't get SYN seq!\n");
- break;
- }
-
- *out_val = pdetail_pr->iserverseq - 1;
- *opt_val_len = sizeof(int);
- }
- break;
-
- case MSO_TCP_ISN_S2C:
- {
- /* TODO 1: �����������ظ�, ���ϲ� */
- struct tcpdetail_private *pdetail_pr;
- UINT32 *out_val = (UINT32 *)opt_val;
- if(STREAM_TYPE_TCP != pstream->type){
- ret = -1;
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:stream type is not tcp!\n");
- break;
- }
- pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- if(pdetail_pr->creat_mod != TCP_CTEAT_LINK_BYSYN){
- ret = -1;
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error: stream create mode is not by SYN!\n");
- break;
- }
-
- if(0 == pdetail_pr->iclientseq){
- ret = -1;
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error: can't get SYN/ACK seq!\n");
- break;
- }
-
- *out_val = pdetail_pr->iclientseq - 1;
- *opt_val_len = sizeof(int);
- }
- break;
-
- case MSO_TCP_SYN_OPT:
- {
- const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
- struct tcp_option **out_val = (struct tcp_option **)opt_val;
- if((pstream_pr->syn_opt_array != NULL) && (pstream_pr->syn_opt_num > 0)){
- *out_val = pstream_pr->syn_opt_array;
- *opt_val_len = pstream_pr->syn_opt_num; /* �˴����dz���, ��ʾopt_array�ĸ��� */
- ret = 0;
- }else{
- ret = -1;
- }
- }
- break;
-
- case MSO_TCP_SYNACK_OPT:
- {
- const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
- struct tcp_option **out_val = (struct tcp_option **)opt_val;
- if((pstream_pr->synack_opt_array != NULL) && (pstream_pr->synack_opt_num > 0)){
- *out_val = pstream_pr->synack_opt_array;
- *opt_val_len = pstream_pr->synack_opt_num; /* �˴����dz���, ��ʾopt_array�ĸ��� */
- ret = 0;
- }else{
- ret = -1;
- }
- }
- break;
-
- case MSO_STREAM_TUNNEL_TYPE:
- {
- const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
- unsigned short *out_val = (unsigned short *)opt_val;
- *out_val = pstream_pr->stream_low_layer_tunnel_type;
- ret = 0;
- }
- break;
-
- case MSO_STREAM_CLOSE_REASON:
- {
- if(pstream->opstate != OP_STATE_CLOSE){
- ret = -1;
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() MSO_STREAM_CLOSE_REASON error: stream %p has not closed!\n", pstream);
- break;
- }
- if(pstream->type != STREAM_TYPE_TCP){
- ret = -1;
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:unsupport stream type:%d!\n", pstream->type);
- break;
- }
- UCHAR *close_reason = (UCHAR *)opt_val;
- struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- *close_reason = pdetail_pr->link_state;
- }
- break;
-
- case MSO_STREAM_VXLAN_INFO:
- if(*opt_val_len != sizeof(struct vxlan_info)){
- return -1;
- }
- ret = sapp_get_vxlan_info_from_streaminfo(pstream, (struct vxlan_info *)opt_val);
- break;
-
- default:
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:unsupport MESA_stream_opt type:%d!\n", opt);
- ret = -1;
- break;
- }
-
- return ret;
-}
-
-int is_proxy_stream(const struct streaminfo *pstream)
-{
- int ret = 0;
-
- switch(pstream->type){
- case STREAM_TYPE_SOCKS4:
- case STREAM_TYPE_SOCKS5:
- case STREAM_TYPE_HTTP_PROXY:
- case STREAM_TYPE_OPENVPN:
- ret = 1;
- break;
-
- default:
- ret = 0;
- break;
- }
-
- return ret;
-}
-
-
-void bind_thread_to_cpuid(int thread_id)
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
-#if(__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__ >= 440)
- cpu_set_t cpuset;
- u_long core_id;
- int res;
- int tot_cpu_num = sysconf(_SC_NPROCESSORS_ONLN);
-
- /* Bind this thread to a specific core */
- if(tot_cpu_num > 1) {
- core_id = (thread_id + 1) % tot_cpu_num;
-
- CPU_ZERO(&cpuset);
- CPU_SET(core_id, &cpuset);
- res = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
- if (res != 0){
- fprintf(stderr, "Error while binding thread %d to core %ld: errno=%i\n",
- thread_id, core_id, res);
- }else{
- printf("[Info]Binding thread %d to core %ld success!\n", thread_id, core_id);
- }
- }
-#endif
-#endif
- return;
-}
-
-
-extern int project_req_terminal_tag_id;
-/* For863, ����Ӧ�ò�����ȡ��TCP���ж�Ӧ���û���ǩ */
-const unsigned char *get_terminal_tag(struct streaminfo *stream)
-{
- unsigned char *terminal_tag;
-
- if(project_req_terminal_tag_id < 0){
- return NULL;
- }
-
- terminal_tag = (unsigned char *)project_req_get_struct(stream, project_req_terminal_tag_id);
-
- return (const unsigned char *)terminal_tag;
-}
-
-int number_is_2powerN(uint n)
-{
- if(n & (n-1)){
- return 0;
- }
-
- return 1;
-}
-
-
-
-void *dictator_malloc(int thread_seq,size_t size)
-{
- /*
- if(malloccount%100000==0)
- {
- printf("malloc=%d,free=%d\n",malloccount,freecount);
- }
- */
-
- if(G_DICTATOR_SW){
-#if USE_MEMPOOL
- return __dictator_malloc(thread_seq, size);
-#endif
- }
-
- return malloc(size);
-}
-void dictator_free(int thread_seq,void *pbuf)
-{
-#if USE_MEMPOOL
- if(G_DICTATOR_SW){
- __dictator_free(thread_seq, pbuf);
- }
- else
-#endif
- {
- free(pbuf);
- }
-}
-
-void *dictator_realloc(int thread_seq, void *ptr, size_t size)
-{
-#if USE_MEMPOOL
- if(G_DICTATOR_SW){
- return __dictator_realloc(thread_seq, ptr, size);
- }
-#endif
-
- return realloc(ptr, size);
-}
-
-/* ��ҵ�������ص�ֵת����ƽ̨�����ֵ, ����PROT_STATE_xxxת��ΪAPP_STATE_xxx */
-char biz_retval_to_platform(char biz_ret)
-{
- char plat_ret = 0;
-
- if(biz_ret & PROT_STATE_GIVEME){
- plat_ret |= APP_STATE_GIVEME;
- }
-
- if(biz_ret & PROT_STATE_DROPME){
- plat_ret |= APP_STATE_DROPME;
- }
-
- if(biz_ret & PROT_STATE_DROPPKT){
- plat_ret |= APP_STATE_DROPPKT;
- }
-
- return plat_ret;
-}
-
-/* ��ƽ̨��stateֵת����ҵ������ֵ, ����OP_STATE_PENDINGתΪSESSION_STATE_PENDING */
-char plat_state_to_biz(char plat_state)
-{
- char biz_ret = SESSION_STATE_CLOSE;
-
- switch(plat_state){
- case OP_STATE_PENDING:
- biz_ret = SESSION_STATE_PENDING;
- break;
-
- case OP_STATE_DATA:
- biz_ret = SESSION_STATE_DATA;
- break;
-
- case OP_STATE_CLOSE:
- biz_ret = SESSION_STATE_CLOSE;
- break;
-
- default:
- break;
- }
-
- return biz_ret;
-}
-
-
-long long sapp_get_cpu_cycle(void)
-{
-#ifdef __x86_64
-#define X86_64_ENV 1
-#endif
-#ifdef __x86_64__
-#define X86_64_ENV 1
-#endif
-
-#ifdef X86_64_ENV
- long long l;
- long long h;
-
- __asm__ volatile("rdtsc" : "=a"(l), "=d"(h));
- return (long long )l | ((long long )h<<32);
-#else
- return 0;
-#endif
-}
-
-#ifdef __cplusplus
-}
-#endif
-
+/*
+ ���ļ���ƽ̨������Ҫ�Ĺ��ܺͺ���,
+ ���ṩ������ҵ�����Ľӿ�, ��MESA_set_stream_opt, printaddr��,
+*/
+#include "stream_internal.h"
+#include "stream_manage.h"
+#include "sysinfo.h"
+#include "packet_io.h"
+#include "packet_io_internal.h"
+#include "project_requirement.h"
+#include "project_internal.h"
+#include "dictator.h"
+#include <MESA/MESA_handle_logger.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <assert.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <pthread.h>
+#include <sys/select.h>
+#include <linux/version.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int G_DICTATOR_SW = 1;
+extern int g_packet_io_thread_num;
+
+extern const raw_ipfrag_list_t *get_raw_frag_list(const struct streaminfo *stream);
+
+int get_opt_from_rawpkt(const void *voidpkt, int type, void *void_value)
+{
+ int ret = 0;
+ const raw_pkt_t *rawpkt = (const raw_pkt_t *)voidpkt;
+
+ if(NULL == voidpkt || NULL == void_value){
+ return -1;
+ }
+
+ if(RAW_PKT_MAGIC_NUM != rawpkt->magic_num){ /* ������Դ��pappƽ̨, ��֧�ִ��๦�� */
+ return -1;
+ }
+
+ switch(type){
+ case RAW_PKT_GET_DATA:
+ {
+ void **out_value = (void **)void_value;
+ *out_value = (void *)rawpkt->raw_pkt_data;
+ }
+ break;
+
+ case RAW_PKT_GET_RAW_PKT_TYPE:
+ {
+ enum addr_type_t *out_value = (enum addr_type_t *)void_value;
+ *out_value = rawpkt->low_layer_type;
+ }
+ break;
+
+ case RAW_PKT_GET_TOT_LEN:
+ {
+ int *out_value = (int *)void_value;
+ *out_value = rawpkt->raw_pkt_len;
+ }
+ break;
+
+ case RAW_PKT_GET_TIMESTAMP:
+ {
+ struct timeval *out_value =(struct timeval *)void_value;
+ memcpy(out_value, &rawpkt->raw_pkt_ts, sizeof(struct timeval));
+ }
+ break;
+
+ case RAW_PKT_GET_THIS_LAYER_HDR:
+ {
+ void **out_value = (void **)void_value;
+ const char *this_layer_hdr = (const char *)rawpkt->raw_pkt_data + rawpkt->offset_to_raw_pkt_hdr;
+ *out_value = (void *)this_layer_hdr;
+ }
+ break;
+
+ case RAW_PKT_GET_THIS_LAYER_REMAIN_LEN:
+ {
+ int *out_value = (int *)void_value;
+ *out_value = rawpkt->raw_pkt_len - rawpkt->offset_to_raw_pkt_hdr;
+ }
+ break;
+
+ default:
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+int get_rawpkt_opt_from_streaminfo(const struct streaminfo *pstream, int type, void *out_value)
+{
+ int ret = -1;
+ const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
+
+ if(NULL == out_value){
+ return -1;
+ }
+
+ if((RAW_PKT_GET_DATA == type)
+ && ((PKT_TYPE_IPREBUILD & pstream->addr.pktipfragtype) != 0)){
+ const raw_ipfrag_list_t *list_tmp = get_raw_frag_list(pstream);
+ if(NULL == list_tmp){
+ ret = -1;
+ }else{
+ const raw_ipfrag_list_t **out_list = (const raw_ipfrag_list_t **)out_value;
+ *out_list = list_tmp;
+ ret = 1;
+ }
+ return ret;
+ }
+
+ return get_opt_from_rawpkt(pstream_pr->raw_pkt, type, out_value);
+}
+
+/*Convert tuple4 to string. Format: 10.0.0.1, 1234->10.0.0.2,5678*/
+const char *printaddr (const struct layer_addr *paddrinfo,int threadindex)
+{
+ static char maxbuf[64+1][128];
+ char *buf=maxbuf[threadindex];
+ char ip_str[64];
+ struct stream_tuple4_v4 *paddr;
+ struct stream_tuple4_v6 *paddr6;
+
+ if(NULL == paddrinfo){
+ return NULL;
+ }
+
+ switch(paddrinfo->addrtype){
+ case ADDR_TYPE_IPV4:
+ {
+ paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr;
+ memset(buf,0,64);
+ //strcpy (buf, int_ntoa (paddr->saddr));
+ inet_ntop(AF_INET, &paddr->saddr, ip_str, 64);
+ strcpy (buf, ip_str);
+ sprintf (buf + strlen (buf), ".%u>", ntohs(paddr->source));
+ //strcat (buf, int_ntoa (paddr->daddr));
+ inet_ntop(AF_INET, &paddr->daddr, ip_str, 64);
+ strcat (buf, ip_str);
+ sprintf (buf + strlen (buf), ".%u", ntohs(paddr->dest));
+ }
+ break;
+
+ case ADDR_TYPE_IPV6:
+ {
+ paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr);
+ memset(buf,0,128);
+ inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64);
+ strcpy (buf, ip_str);
+ sprintf (buf + strlen (buf), ".%u>", ntohs(paddr6->source));
+ inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64);
+ strcat (buf, ip_str);
+ sprintf (buf + strlen (buf), ".%u", ntohs(paddr6->dest));
+ }
+ break;
+
+ case __ADDR_TYPE_IP_PAIR_V4:
+ {
+ paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr;
+ memset(buf,0,128);
+ //strcpy (buf, int_ntoa (paddr->saddr));
+ inet_ntop(AF_INET, &paddr->saddr, ip_str, 64);
+ strcpy (buf, ip_str);
+ strcat (buf, ">");
+ inet_ntop(AF_INET, &paddr->daddr, ip_str, 64);
+ strcat (buf, ip_str);
+ }
+ break;
+
+ case __ADDR_TYPE_IP_PAIR_V6:
+ {
+ paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr);
+ memset(buf,0,128);
+ inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64);
+ strcpy (buf, ip_str);
+ strcat (buf, ">");
+ inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64);
+ strcat (buf, ip_str);
+ }
+ break;
+
+ default:
+ {
+ return (const char *)"Not support layer type";
+ }
+ break;
+ }
+
+ return buf;
+}
+
+/*
+ This is a reentrant version of printaddr(),
+ Convert tuple4 to string store in out_buf.
+ Format: 10.0.0.1, 1234->10.0.0.2,5678.
+*/
+const char *printaddr_r(const struct layer_addr *paddrinfo, char *out_buf, int out_buf_len)
+{
+#define __MIN_ADDR_STR_LEN (20) /* ��С��ַ�ַ�������, ����:1.1.1.1.1>2.2.2.2.2 */
+ char maxbuf[128];
+ char *buf=maxbuf;
+ char ip_str[64];
+ int addr_str_len;
+ struct stream_tuple4_v4 *paddr;
+ struct stream_tuple4_v6 *paddr6;
+
+ if((NULL == paddrinfo) || (NULL == out_buf)){
+ return "invalid args";
+ }
+
+ if(paddrinfo->addrtype==ADDR_TYPE_IPV4)
+ {
+ paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr;
+ memset(buf,0,128);
+ //strcpy (buf, int_ntoa (paddr->saddr));
+ inet_ntop(AF_INET, &paddr->saddr, ip_str, 64);
+ strcpy (buf, ip_str);
+ sprintf (buf + strlen (buf), ".%u>", ntohs(paddr->source));
+ //strcat (buf, int_ntoa (paddr->daddr));
+ inet_ntop(AF_INET, &paddr->daddr, ip_str, 64);
+ strcat (buf, ip_str);
+ sprintf (buf + strlen (buf), ".%u", ntohs(paddr->dest));
+ }
+ //to addjust
+ else if(paddrinfo->addrtype==ADDR_TYPE_IPV6)
+ {
+ paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr);
+ memset(buf,0,128);
+ inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64);
+ strcpy (buf, ip_str);
+ sprintf (buf + strlen (buf), ".%u>", ntohs(paddr6->source));
+ inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64);
+ strcat (buf, ip_str);
+ sprintf (buf + strlen (buf), ".%u", ntohs(paddr6->dest));
+ }
+ else
+ {
+ return (const char *)"Not support layer type";
+ }
+
+ addr_str_len = strlen(buf) + 1; /* add EOF */
+ if(addr_str_len > out_buf_len){
+ return (const char *)"buf len not enough";
+ }
+
+ memcpy(out_buf, buf, addr_str_len);
+
+ return out_buf;
+}
+
+
+struct layer_addr * layer_addr_dup(const struct layer_addr *stack_info)
+{
+ void *addr_value;
+ struct layer_addr *heap_addr = (struct layer_addr *)malloc(sizeof(struct layer_addr));
+ addr_value = malloc(stack_info->addrlen);
+
+ memcpy(heap_addr, stack_info, sizeof(struct layer_addr));
+ memcpy(addr_value, stack_info->paddr, stack_info->addrlen);
+ heap_addr->paddr = addr_value;
+
+ return heap_addr;
+}
+
+void layer_addr_free(struct layer_addr *paddrinfo)
+{
+ free(paddrinfo->paddr);
+ free(paddrinfo);
+}
+
+int get_thread_count(void)
+{
+ return g_packet_io_thread_num;
+}
+
+
+int MESA_set_stream_opt(const struct streaminfo *pstream, enum MESA_stream_opt opt, void *opt_val, int opt_val_len)
+{
+ int ret = -1;
+
+ if((NULL == opt_val) || (opt_val_len <= 0)){
+ return -1;
+ }
+
+ switch((int)opt){
+ case (int)MSO_MAX_UNORDER:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ printf("MESA_set_stream_opt() error:stream type is not tcp!\n");
+ ret = -1;
+ break;
+ }
+ if(opt_val_len != sizeof(struct max_unorder_opt)){
+ printf("MESA_set_stream_opt() error:opt_val_len invalid, must be sizeof(struct max_unorder_opt)\n");
+ ret = -1;
+ break;
+ }
+ struct max_unorder_opt *max_uorder = (struct max_unorder_opt *)opt_val;
+ ret = tcp_set_single_stream_max_unorder(pstream, max_uorder->stream_dir, max_uorder->max_unorder_val);
+ }
+ break;
+
+ case (int)MSO_NEED_ACK:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ printf("MESA_set_stream_opt() error:stream type is not tcp!\n");
+ ret = -1;
+ break;
+ }
+ unsigned char nack = *((unsigned char *)opt_val);
+ struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ pdetail_pr->needackflag = nack;
+ ret = 0;
+ }
+ break;
+
+ case (int)MSO_TAKEOVER:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ printf("MESA_set_stream_opt() error:stream type is not tcp!\n");
+ ret = -1;
+ break;
+ }
+ int takeover = *((int *)opt_val);
+ struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail);
+ pdetail_pr->takeoverflag = takeover;
+ ret = 0;
+ }
+ break;
+
+ case (int)MSO_TIMEOUT:
+ {
+ if(sizeof(short) != opt_val_len){
+ printf("MESA_set_stream_opt() error:opt_val_len invalid, must be sizeof(short)\n");
+ ret = -1;
+ break;
+ }
+ unsigned short tmout = *((unsigned short *)opt_val);
+ ret = stream_set_single_stream_timeout(pstream, tmout);
+ }
+ break;
+
+ case (int)MSO_IGNORE_RST_FIN:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ printf("MESA_set_stream_opt() error: stream type is not tcp!\n");
+ ret = -1;
+ break;
+ }
+ unsigned char igrstfin = *((unsigned char *)opt_val);
+ struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ pdetail_pr->ignore_rst_fin = igrstfin;
+ ret = 0;
+ }
+ break;
+
+ default:
+ printf("MESA_set_stream_opt() error: unsupport MESA_stream_opt type!\n");
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+
+static inline int tcp_get_single_stream_max_unorder(const struct streaminfo *pstream, void *opt_val, int *opt_val_len)
+{
+ struct max_unorder_opt out_val;
+ struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private *)pstream->pdetail;
+ UINT16 out_uorder_C2S = 0, out_uorder_S2C = 0;
+
+ memset(&out_val, 0, sizeof(struct max_unorder_opt));
+ if((pdetail_pr->pserver != NULL) && (tcp_default_unorder != pdetail_pr->pserver->maxunorder)){
+ out_uorder_C2S = pdetail_pr->pserver->maxunorder;
+ out_val.stream_dir |= DIR_C2S;
+ }
+
+ if((pdetail_pr->pclient != NULL) && (tcp_default_unorder != pdetail_pr->pclient->maxunorder)){
+ out_uorder_S2C = pdetail_pr->pclient->maxunorder;
+ out_val.stream_dir |= DIR_S2C;
+ }
+
+ out_val.max_unorder_val = (out_uorder_C2S > out_uorder_S2C)?out_uorder_C2S: out_uorder_S2C;
+
+ memcpy(opt_val, &out_val, sizeof(struct max_unorder_opt));
+
+ *opt_val_len = sizeof(struct max_unorder_opt);
+
+ return 0;
+}
+
+
+static void sapp_mac_addr_to_long(const unsigned char *mac_addr, unsigned long long *smac_integer_type)
+{
+ int i;
+ char *ptr = (char *)smac_integer_type;
+
+ ptr += 5; /* ָ��long long �ĵ�6���ֽ� */
+
+ for(i = 0; i < 6; i++){
+ *ptr-- = *mac_addr++; /* �������ݰ���mac�����λ, copy��long long���������λ(��ȥ���2���ֽں�) */
+ }
+}
+
+static int sapp_get_vxlan_info_from_streaminfo(const struct streaminfo *pstream, struct vxlan_info *vxinfo)
+{
+#define GDEV_SMAC_MASK_ENCAP_TYPE (0x00000000000F0000)
+#define GDEV_SMAC_MASK_ENTRANCE_ID (0x0000000000007C00)
+#define GDEV_SMAC_MASK_DEV_ID (0x00000000000003F0)
+#define GDEV_SMAC_MASK_LINK_ID (0x000000000000000E)
+#define GDEV_SMAC_MASK_LINK_DIR (0x0000000000000001)
+
+
+ int ret, i;
+ const struct streaminfo *mim_stream = pstream->pfather;
+ const struct layer_addr_mac_in_mac *mim_addr;
+ const struct layer_addr_mac *mac_addr;
+ unsigned char *ptr;
+ unsigned long long smac_integer_type; /* 48bit macת��Ϊ64bit�ij��������ִ洢, ���ڲ��� */
+
+ while(mim_stream){//���ڶ��mac��ַ�������ֻ�������MAC��ַȡvxlan_info
+ if((ADDR_TYPE_MAC_IN_MAC == mim_stream->addr.addrtype || ADDR_TYPE_MAC == mim_stream->addr.addrtype) &&
+ (mim_stream->pfather == NULL)){
+ break;
+ }else{
+ mim_stream = mim_stream->pfather;
+ }
+ }
+
+ if(NULL == mim_stream){
+ return -1;
+ }
+
+ memset(vxinfo, 0, sizeof(struct vxlan_info));
+
+ if(ADDR_TYPE_MAC_IN_MAC == mim_stream->addr.addrtype)
+ {
+ mim_addr = mim_stream->addr.mimac;
+ sapp_mac_addr_to_long(mim_addr->outer_src_mac, &smac_integer_type);
+ }
+ else
+ {
+ mac_addr = mim_stream->addr.mac;
+ sapp_mac_addr_to_long(mac_addr->src_mac, &smac_integer_type);
+ }
+ vxinfo->encap_type = (smac_integer_type & GDEV_SMAC_MASK_ENCAP_TYPE) >> 16;
+ vxinfo->entrance_id = (smac_integer_type & GDEV_SMAC_MASK_ENTRANCE_ID) >> 10;
+ vxinfo->dev_id = (smac_integer_type & GDEV_SMAC_MASK_DEV_ID) >> 4;
+ vxinfo->link_id = (smac_integer_type & GDEV_SMAC_MASK_LINK_ID ) >> 1;
+ vxinfo->link_dir = (smac_integer_type & GDEV_SMAC_MASK_LINK_DIR);
+
+ if(ADDR_TYPE_MAC_IN_MAC == mim_stream->addr.addrtype)
+ {
+ ptr = vxinfo->inner_smac;
+ for(i = 0; i < 6; i++, ptr += 3){
+ sprintf((char *)ptr, "%02x:", mim_addr->inner_src_mac[i]);
+ }
+ vxinfo->inner_smac[17] = '\0'; /* ���һλ���� */
+ memcpy(vxinfo->inner_smac_hex, mim_addr->inner_src_mac, 6);
+
+ ptr = vxinfo->inner_dmac;
+ for(i = 0; i < 6; i++, ptr += 3){
+ sprintf((char *)ptr, "%02x:", mim_addr->inner_dst_mac[i]);
+ }
+ vxinfo->inner_dmac[17] = '\0'; /* ���һλ���� */
+ memcpy(vxinfo->inner_dmac_hex, mim_addr->inner_dst_mac, 6);
+ }
+ else
+ {
+ ptr = vxinfo->inner_smac;
+ for(i = 0; i < 6; i++, ptr += 3){
+ sprintf((char *)ptr, "%02x:", mac_addr->src_mac[i]);
+ }
+ vxinfo->inner_smac[17] = '\0'; /* ���һλ���� */
+ memcpy(vxinfo->inner_smac_hex, mac_addr->src_mac, 6);
+
+ ptr = vxinfo->inner_dmac;
+ for(i = 0; i < 6; i++, ptr += 3){
+ sprintf((char *)ptr, "%02x:", mac_addr->dst_mac[i]);
+ }
+ vxinfo->inner_dmac[17] = '\0'; /* ���һλ���� */
+ memcpy(vxinfo->inner_dmac_hex, mac_addr->dst_mac, 6);
+ }
+ return 0;
+}
+
+int MESA_get_stream_opt(const struct streaminfo *pstream, enum MESA_stream_opt opt, void *opt_val, int *opt_val_len)
+{
+ int ret = 0;
+
+ if((NULL == opt_val) || (NULL == opt_val_len) || (*opt_val_len <= 0)){
+ return -1;
+ }
+
+ switch((int)opt){
+ case (int)MSO_MAX_UNORDER:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:stream type is not tcp!\n");
+ ret = -1;
+ break;
+ }
+ if(*opt_val_len < (int)sizeof(struct max_unorder_opt)){
+ sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:opt_val_len invalid, must be sizeof(struct max_unorder_opt)\n");
+ ret = -1;
+ break;
+ }
+ *opt_val_len = sizeof(struct max_unorder_opt);
+ ret = tcp_get_single_stream_max_unorder(pstream, opt_val, opt_val_len);
+ }
+ break;
+
+ case (int)MSO_NEED_ACK:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:stream type is not tcp!\n");
+ ret = -1;
+ break;
+ }
+ unsigned char *nack = (unsigned char *)opt_val;
+ struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ *nack = pdetail_pr->needackflag;
+ *opt_val_len = sizeof(char);
+ }
+ break;
+
+ case (int)MSO_TAKEOVER:
+ {
+ if(*opt_val_len < (int)sizeof(int)){
+ ret = -1;
+ break;
+ }
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:stream type is not tcp!\n");
+ ret = -1;
+ break;
+ }
+ int *takeover = (int *)opt_val;
+ struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail);
+ *takeover = pdetail_pr->takeoverflag;
+ *opt_val_len = sizeof(int);
+ }
+ break;
+
+ case (int)MSO_TIMEOUT:
+ {
+ if(sizeof(short) != *opt_val_len){
+ sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:opt_val_len invalid, must be sizeof(short)\n");
+ ret = -1;
+ break;
+ }
+ unsigned short *tmout = (unsigned short *)opt_val;
+ struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream;
+ *tmout = pstream_pr->timeout;
+ *opt_val_len = sizeof(short);
+ }
+ break;
+
+ case (int)MSO_IGNORE_RST_FIN:
+ {
+ if(STREAM_TYPE_TCP != pstream->type){
+ sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:stream type is not tcp!\n");
+ ret = -1;
+ break;
+ }
+ unsigned char *igrstfin = (unsigned char *)opt_val;
+ struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ *igrstfin = pdetail_pr->ignore_rst_fin;
+ }
+ break;
+
+ case MSO_TCP_CREATE_LINK_MODE:
+ {
+ struct tcpdetail_private *pdetail_pr;
+ UCHAR *out_val = (UCHAR *)opt_val;
+ if(STREAM_TYPE_TCP != pstream->type){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:stream type is not tcp!\n");
+ break;
+ }
+
+ pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ *out_val = pdetail_pr->creat_mod;
+ *opt_val_len = sizeof(char);
+ }
+ break;
+
+ case MSO_TCP_ISN_C2S:
+ {
+ struct tcpdetail_private *pdetail_pr;
+ UINT32 *out_val = (UINT32 *)opt_val;
+ if(STREAM_TYPE_TCP != pstream->type){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:stream type is not tcp!\n");
+ break;
+ }
+
+ pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ if(pdetail_pr->creat_mod != TCP_CTEAT_LINK_BYSYN){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error: stream create mode is not by SYN!\n");
+ break;
+ }
+ if(0 == pdetail_pr->iserverseq){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error: can't get SYN seq!\n");
+ break;
+ }
+
+ *out_val = pdetail_pr->iserverseq - 1;
+ *opt_val_len = sizeof(int);
+ }
+ break;
+
+ case MSO_TCP_ISN_S2C:
+ {
+ /* TODO 1: �����������ظ�, ���ϲ� */
+ struct tcpdetail_private *pdetail_pr;
+ UINT32 *out_val = (UINT32 *)opt_val;
+ if(STREAM_TYPE_TCP != pstream->type){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:stream type is not tcp!\n");
+ break;
+ }
+ pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ if(pdetail_pr->creat_mod != TCP_CTEAT_LINK_BYSYN){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error: stream create mode is not by SYN!\n");
+ break;
+ }
+
+ if(0 == pdetail_pr->iclientseq){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error: can't get SYN/ACK seq!\n");
+ break;
+ }
+
+ *out_val = pdetail_pr->iclientseq - 1;
+ *opt_val_len = sizeof(int);
+ }
+ break;
+
+ case MSO_TCP_SYN_OPT:
+ {
+ const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
+ struct tcp_option **out_val = (struct tcp_option **)opt_val;
+ if((pstream_pr->syn_opt_array != NULL) && (pstream_pr->syn_opt_num > 0)){
+ *out_val = pstream_pr->syn_opt_array;
+ *opt_val_len = pstream_pr->syn_opt_num; /* �˴����dz���, ��ʾopt_array�ĸ��� */
+ ret = 0;
+ }else{
+ ret = -1;
+ }
+ }
+ break;
+
+ case MSO_TCP_SYNACK_OPT:
+ {
+ const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
+ struct tcp_option **out_val = (struct tcp_option **)opt_val;
+ if((pstream_pr->synack_opt_array != NULL) && (pstream_pr->synack_opt_num > 0)){
+ *out_val = pstream_pr->synack_opt_array;
+ *opt_val_len = pstream_pr->synack_opt_num; /* �˴����dz���, ��ʾopt_array�ĸ��� */
+ ret = 0;
+ }else{
+ ret = -1;
+ }
+ }
+ break;
+
+ case MSO_STREAM_TUNNEL_TYPE:
+ {
+ const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
+ unsigned short *out_val = (unsigned short *)opt_val;
+ *out_val = pstream_pr->stream_low_layer_tunnel_type;
+ ret = 0;
+ }
+ break;
+
+ case MSO_STREAM_CLOSE_REASON:
+ {
+ if(pstream->opstate != OP_STATE_CLOSE){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() MSO_STREAM_CLOSE_REASON error: stream %p has not closed!\n", pstream);
+ break;
+ }
+ if(pstream->type != STREAM_TYPE_TCP){
+ ret = -1;
+ sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:unsupport stream type:%d!\n", pstream->type);
+ break;
+ }
+ UCHAR *close_reason = (UCHAR *)opt_val;
+ struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
+ *close_reason = pdetail_pr->link_state;
+ }
+ break;
+
+ case MSO_STREAM_VXLAN_INFO:
+ if(*opt_val_len != sizeof(struct vxlan_info)){
+ return -1;
+ }
+ ret = sapp_get_vxlan_info_from_streaminfo(pstream, (struct vxlan_info *)opt_val);
+ break;
+
+ default:
+ sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:unsupport MESA_stream_opt type:%d!\n", opt);
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+int is_proxy_stream(const struct streaminfo *pstream)
+{
+ int ret = 0;
+
+ switch(pstream->type){
+ case STREAM_TYPE_SOCKS4:
+ case STREAM_TYPE_SOCKS5:
+ case STREAM_TYPE_HTTP_PROXY:
+ case STREAM_TYPE_OPENVPN:
+ ret = 1;
+ break;
+
+ default:
+ ret = 0;
+ break;
+ }
+
+ return ret;
+}
+
+
+void bind_thread_to_cpuid(int thread_id)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
+#if(__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__ >= 440)
+ cpu_set_t cpuset;
+ u_long core_id;
+ int res;
+ int tot_cpu_num = sysconf(_SC_NPROCESSORS_ONLN);
+
+ /* Bind this thread to a specific core */
+ if(tot_cpu_num > 1) {
+ core_id = (thread_id + 1) % tot_cpu_num;
+
+ CPU_ZERO(&cpuset);
+ CPU_SET(core_id, &cpuset);
+ res = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
+ if (res != 0){
+ fprintf(stderr, "Error while binding thread %d to core %ld: errno=%i\n",
+ thread_id, core_id, res);
+ }else{
+ printf("[Info]Binding thread %d to core %ld success!\n", thread_id, core_id);
+ }
+ }
+#endif
+#endif
+ return;
+}
+
+
+extern int project_req_terminal_tag_id;
+/* For863, ����Ӧ�ò�����ȡ��TCP���ж�Ӧ���û���ǩ */
+const unsigned char *get_terminal_tag(struct streaminfo *stream)
+{
+ unsigned char *terminal_tag;
+
+ if(project_req_terminal_tag_id < 0){
+ return NULL;
+ }
+
+ terminal_tag = (unsigned char *)project_req_get_struct(stream, project_req_terminal_tag_id);
+
+ return (const unsigned char *)terminal_tag;
+}
+
+int number_is_2powerN(uint n)
+{
+ if(n & (n-1)){
+ return 0;
+ }
+
+ return 1;
+}
+
+
+
+void *dictator_malloc(int thread_seq,size_t size)
+{
+ /*
+ if(malloccount%100000==0)
+ {
+ printf("malloc=%d,free=%d\n",malloccount,freecount);
+ }
+ */
+
+ if(G_DICTATOR_SW){
+#if USE_MEMPOOL
+ return __dictator_malloc(thread_seq, size);
+#endif
+ }
+
+ return malloc(size);
+}
+void dictator_free(int thread_seq,void *pbuf)
+{
+#if USE_MEMPOOL
+ if(G_DICTATOR_SW){
+ __dictator_free(thread_seq, pbuf);
+ }
+ else
+#endif
+ {
+ free(pbuf);
+ }
+}
+
+void *dictator_realloc(int thread_seq, void *ptr, size_t size)
+{
+#if USE_MEMPOOL
+ if(G_DICTATOR_SW){
+ return __dictator_realloc(thread_seq, ptr, size);
+ }
+#endif
+
+ return realloc(ptr, size);
+}
+
+/* ��ҵ�������ص�ֵת����ƽ̨�����ֵ, ����PROT_STATE_xxxת��ΪAPP_STATE_xxx */
+char biz_retval_to_platform(char biz_ret)
+{
+ char plat_ret = 0;
+
+ if(biz_ret & PROT_STATE_GIVEME){
+ plat_ret |= APP_STATE_GIVEME;
+ }
+
+ if(biz_ret & PROT_STATE_DROPME){
+ plat_ret |= APP_STATE_DROPME;
+ }
+
+ if(biz_ret & PROT_STATE_DROPPKT){
+ plat_ret |= APP_STATE_DROPPKT;
+ }
+
+ return plat_ret;
+}
+
+/* ��ƽ̨��stateֵת����ҵ������ֵ, ����OP_STATE_PENDINGתΪSESSION_STATE_PENDING */
+char plat_state_to_biz(char plat_state)
+{
+ char biz_ret = SESSION_STATE_CLOSE;
+
+ switch(plat_state){
+ case OP_STATE_PENDING:
+ biz_ret = SESSION_STATE_PENDING;
+ break;
+
+ case OP_STATE_DATA:
+ biz_ret = SESSION_STATE_DATA;
+ break;
+
+ case OP_STATE_CLOSE:
+ biz_ret = SESSION_STATE_CLOSE;
+ break;
+
+ default:
+ break;
+ }
+
+ return biz_ret;
+}
+
+
+long long sapp_get_cpu_cycle(void)
+{
+#ifdef __x86_64
+#define X86_64_ENV 1
+#endif
+#ifdef __x86_64__
+#define X86_64_ENV 1
+#endif
+
+#ifdef X86_64_ENV
+ long long l;
+ long long h;
+
+ __asm__ volatile("rdtsc" : "=a"(l), "=d"(h));
+ return (long long )l | ((long long )h<<32);
+#else
+ return 0;
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/dealpkt/stream_manage.c b/dealpkt/stream_manage.c
index 7403e93..6adaa9e 100644
--- a/dealpkt/stream_manage.c
+++ b/dealpkt/stream_manage.c
@@ -2572,6 +2572,13 @@ int get_stream_carry_tunnel_type(const struct streaminfo *this_stream,
const struct streaminfo *pfather = this_stream->pfather;
switch(this_stream->addr.addrtype){
+ case ADDR_TYPE_MAC:
+ pfather = this_stream->pfather; //
+ if(pfather != NULL){
+ *tunnel_type = (unsigned short)STREAM_TUNNEL_MULTI_MAC;
+ }
+ break;
+
case ADDR_TYPE_IPV4:
pfather = this_stream->pfather; /* IP-TCP/UDP����Ϊ��һ������, ����pfatherָ�� */
if(pfather != NULL){
diff --git a/entry/CMakeLists.txt b/entry/CMakeLists.txt
index ecd7cb0..07555ae 100644
--- a/entry/CMakeLists.txt
+++ b/entry/CMakeLists.txt
@@ -9,11 +9,24 @@ include_directories(${CMAKE_SOURCE_DIR}/dealpkt)
include_directories(${CMAKE_SOURCE_DIR}/packet_io)
add_executable(sapp sapp_init.c sapp_main.c sapp_global_val.c)
+target_compile_options(sapp PUBLIC ${MEM_POOL_DEFINITIONS})
target_link_libraries(sapp nsl pthread dl m pcap)
-target_link_libraries(sapp MESA_handle_logger MESA_prof_load sapp_assistant gdev_assistant)
-
-set(SAPP_MODULES -Wl,--whole-archive iknow timestamp_record dictator2 md5 symbol_check MESA_sleep MESA_socket_wrap packet_io dealpkt project plugctrl -Wl,--no-whole-archive)
-target_link_libraries(sapp ${SAPP_MODULES} ${SAPP_DEPEND_DYN_LIB})
+target_link_libraries(sapp MESA_handle_logger MESA_prof_load)
+target_link_libraries(sapp sapp_assistant gdev_assistant)
+
+
+set(SAPP_MODULES iknow timestamp_record md5 symbol_check MESA_sleep MESA_socket_wrap packet_io dealpkt project plugctrl)
+#if(OPT_USE_DICTATOR OR OPT_USE_DICTATOR_DEBUG)
+# set(SAPP_MODULES ${SAPP_MODULES} dictator2 )
+#endif()
+#
+#if(ENABLE_STATIC_LINK)
+# set(SAPP_MODULES ${SAPP_MODULES} sapp_assistant gdev_assistant )
+#else()
+# target_link_libraries(sapp sapp_assistant gdev_assistant)
+#endif()
+
+target_link_libraries(sapp -Wl,--whole-archive ${SAPP_MODULES} -Wl,--no-whole-archive ${SAPP_DEPEND_DYN_LIB})
if(CAPTURE_MODE MATCHES "PAG")
target_link_libraries(sapp pag)
diff --git a/entry/Makefile b/entry/Makefile
index 0626c1f..0bd67bd 100644
--- a/entry/Makefile
+++ b/entry/Makefile
@@ -1,86 +1,86 @@
-TARGET=sapp
-
-all: $(TARGET)
-LIB_PATH=-L../lib
-CFLAGS += -DPLATFORM_NSDPF_PAPP=1
-
-ifeq ($(USE_PAG_GET_FRAME), $(YES))
-CFLAGS += -DUSE_PAG_GET_FRAME=1
-else
-CFLAGS += -DUSE_PAG_GET_FRAME=0
-endif
-
-ifeq ($(USE_MEM_POOL), $(YES))
-CFLAGS += -DUSE_MEMPOOL=1
-endif
-
-CFLAGS += -rdynamic
-
-ifeq ($(USE_MEM_POOL), $(YES))
-#LD_DICTATOR = -Wl,-wrap,malloc -Wl,-wrap,calloc -Wl,-wrap,free -Wl,-wrap,realloc
-WHOLE_ARCH=../lib/libdealpkt.a ../lib/libproject.a ../lib/libMESA_sleep.a ../lib/libdictator.a ../lib/libtimestamp_record.a
-WHOLE_ARCH+=../lib/libavltree.a
-else
-WHOLE_ARCH=../lib/libdealpkt.a ../lib/libproject.a ../lib/libMESA_sleep.a ../lib/libtimestamp_record.a
-WHOLE_ARCH+=../lib/libavltree.a
-endif
-
-LDFLAGS =
-LDFLAGS += $(LD_DICTATOR)
-
-LIB=../lib/libpacket_io.a
-LIB+=../lib/plugctrl.a
-LIB+=../lib/libmd5.a
-LIB+=../lib/librbtree.a
-LIB+= ../lib/libsymbol_check.a
-LIB+= ../lib/libMESA_socket_wrap.a
-
-ifeq ($(debug), $(_DEBUG2))
-LIB += ../lib/libiknow.a -lpcap
-endif
-
-ifeq ($(IIEFD_DUAL_STACK), $(YES))
-CFLAGS += -g -DIIEFD_DUAL_STACK=1
-endif
-ifeq ($(iomode), $(_MODE_DPDK))
-CFLAGS += -DIOMODE_DPDK=1
-endif
-
-INC+=-I../include
-INC+=-I../include/net
-INC+=-I../include/support
-INC+=-I../dealpkt
-INC += -I../packet_io
-INC+=-I/opt/MESA/include
-INC+=-I/opt/MESA/include/MESA
-INC+=-I/opt/MESA/include/MESA/stream_inc
-
-LIB += -L/opt/MESA/lib -lpthread -ldl
-LIB += -lMESA_htable -lMESA_handle_logger -lMESA_prof_load
-LIB += -lMESA_field_stat2
-LIB += -lsapp_assistant
-#LIB += -lsesame_door
-
-#DEP=support/libMESA_prof_load.so
-#DEP+=support/libMESA_htable.so
-#DEP+=support/libnet_common.so
-#DEP+=support/old_Profile.so
-#DEP+=support/libMESA_handle_logger.so
-#DEP+=support/liblogger.so
-
-iiefd_dual_stack: sapp_main.o sapp_init.o
-
-$(TARGET):sapp_main.o sapp_init.o sapp_global_val.o
- g++ -g -Wl,--export-dynamic -o $@ $(CFLAGS) $(INC) $^ $(LDFLAGS) $(LIB_PATH) -Wl,--whole-archive $(WHOLE_ARCH) -Wl,--no-whole-archive $(LIB)
- cp ../packet_io/*.so ../run/platform_lib/;
- cp $@ ../run/;
- ldconfig;
-
-.c.o:
- $(CC) -c $(CFLAGS) -I. $(INC) $<
-
-.cpp.o:
- $(CCC) -c $(CFLAGS) -I. $(INC) $<
-
-clean:
- rm -f $(TARGET) *.o
+TARGET=sapp
+
+all: $(TARGET)
+LIB_PATH=-L../lib
+CFLAGS += -DPLATFORM_NSDPF_PAPP=1
+
+ifeq ($(USE_PAG_GET_FRAME), $(YES))
+CFLAGS += -DUSE_PAG_GET_FRAME=1
+else
+CFLAGS += -DUSE_PAG_GET_FRAME=0
+endif
+
+ifeq ($(USE_MEM_POOL), $(YES))
+CFLAGS += -DUSE_MEMPOOL=1
+endif
+
+CFLAGS += -rdynamic
+
+ifeq ($(USE_MEM_POOL), $(YES))
+#LD_DICTATOR = -Wl,-wrap,malloc -Wl,-wrap,calloc -Wl,-wrap,free -Wl,-wrap,realloc
+WHOLE_ARCH=../lib/libdealpkt.a ../lib/libproject.a ../lib/libMESA_sleep.a ../lib/libdictator.a ../lib/libtimestamp_record.a
+WHOLE_ARCH+=../lib/libavltree.a
+else
+WHOLE_ARCH=../lib/libdealpkt.a ../lib/libproject.a ../lib/libMESA_sleep.a ../lib/libtimestamp_record.a
+WHOLE_ARCH+=../lib/libavltree.a
+endif
+
+LDFLAGS =
+LDFLAGS += $(LD_DICTATOR)
+
+LIB=../lib/libpacket_io.a
+LIB+=../lib/plugctrl.a
+LIB+=../lib/libmd5.a
+LIB+=../lib/librbtree.a
+LIB+= ../lib/libsymbol_check.a
+LIB+= ../lib/libMESA_socket_wrap.a
+
+ifeq ($(debug), $(_DEBUG2))
+LIB += ../lib/libiknow.a -lpcap
+endif
+
+ifeq ($(IIEFD_DUAL_STACK), $(YES))
+CFLAGS += -g -DIIEFD_DUAL_STACK=1
+endif
+ifeq ($(iomode), $(_MODE_DPDK))
+CFLAGS += -DIOMODE_DPDK=1
+endif
+
+INC+=-I../include
+INC+=-I../include/net
+INC+=-I../include/support
+INC+=-I../dealpkt
+INC += -I../packet_io
+INC+=-I/opt/MESA/include
+INC+=-I/opt/MESA/include/MESA
+INC+=-I/opt/MESA/include/MESA/stream_inc
+
+LIB += -L/opt/MESA/lib -lpthread -ldl
+LIB += -lMESA_htable -lMESA_handle_logger -lMESA_prof_load
+LIB += -lMESA_field_stat2
+LIB += -lsapp_assistant
+#LIB += -lsesame_door
+
+#DEP=support/libMESA_prof_load.so
+#DEP+=support/libMESA_htable.so
+#DEP+=support/libnet_common.so
+#DEP+=support/old_Profile.so
+#DEP+=support/libMESA_handle_logger.so
+#DEP+=support/liblogger.so
+
+iiefd_dual_stack: sapp_main.o sapp_init.o
+
+$(TARGET):sapp_main.o sapp_init.o sapp_global_val.o
+ g++ -g -Wl,--export-dynamic -o $@ $(CFLAGS) $(INC) $^ $(LDFLAGS) $(LIB_PATH) -Wl,--whole-archive $(WHOLE_ARCH) -Wl,--no-whole-archive $(LIB)
+ cp ../packet_io/*.so ../run/platform_lib/;
+ cp $@ ../run/;
+ #ldconfig;
+
+.c.o:
+ $(CC) -c $(CFLAGS) -I. $(INC) $<
+
+.cpp.o:
+ $(CCC) -c $(CFLAGS) -I. $(INC) $<
+
+clean:
+ rm -f $(TARGET) *.o
diff --git a/entry/sapp_init.c b/entry/sapp_init.c
index c2352f0..0b285c8 100644
--- a/entry/sapp_init.c
+++ b/entry/sapp_init.c
@@ -125,7 +125,7 @@ int MESA_platform_init(int argc, char *argv[])
/* 2016-09-22 lijia add, dictator�ڵ�һ�α�����ʱ�г�ʼ������, ��ֹ���߳������ͻ, ƽ̨�ȵ���һ��, ��Ҫ��ȡ�����ļ����� */
MESA_load_profile_int_def("conf/main.conf","Module", "dictator_switch", &G_DICTATOR_SW, 1);
sapp_dictator_init();
-
+
MESA_load_profile_int_def((char *)"conf/main.conf", (char *)"ShowStatInfo", (char *)"platform_log_level", &g_sapp_log_level, 10);
g_sapp_log_handle = MESA_create_runtime_log_handle("./log/runtimelog", g_sapp_log_level);
if(NULL == g_sapp_log_handle)
diff --git a/include/stream_inc/stream_base.h b/include/stream_inc/stream_base.h
index 3938996..25648c1 100644
--- a/include/stream_inc/stream_base.h
+++ b/include/stream_inc/stream_base.h
@@ -1,529 +1,530 @@
-#ifndef _APP_STREAM_BASE_H_
-#define _APP_STREAM_BASE_H_
-
-#define STREAM_BASE_H_VERSION (20170616)
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip6.h>
-#include <netinet/tcp.h>
-#include <netinet/udp.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef UINT8
-typedef unsigned char UINT8;
-#endif
-#ifndef UCHAR
-typedef unsigned char UCHAR;
-#endif
-#ifndef UINT16
-typedef unsigned short UINT16;
-#endif
-
-#ifndef UINT32
-typedef unsigned int UINT32;
-#endif
-#ifndef UINT64
-typedef unsigned long long UINT64;
-#endif
-
-/* CHN : ������� */
-/* ENG : stream direction definition*/
-#define DIR_C2S 0x01
-#define DIR_S2C 0x02
-#define DIR_DOUBLE 0x03
-
-/* CHN : ����ײ㴫�䷽����,����ģʽ������ */
-/* ENG : network topology route direction, is valid in serial mode */
-#define DIR_ROUTE_UP 0x00
-#define DIR_ROUTE_DOWN 0x01
-
-/* CHN : ���������Ͷ��� */
-/* ENG : single packet type definition */
-#define PKT_TYPE_NORMAL (0x0) /* normal, common */
-#define PKT_TYPE_IPREBUILD (1<<0) /* ip frag reassembled packet; ip��Ƭ���鱨�� */
-#define PKT_TYPE_TCPUNORDER (1<<1) /* TCP out of order packet; TCP������ */
-#define PKT_TYPE_TCPREORDER (1<<2) /* TCP sequential packet; TCP��������õ����ݰ� */
-#define PKT_TYPE_TCPRETRANS (1<<3) /* TCP retransmit packet; TCP�ش����� */
-#define PKT_TYPE_IP_FRAG (1<<4) /* IP frag packet; IP��Ƭ�� */
-#define PKT_TYPE_IP_FRAG_LAST (1<<5) /* last IP frag packet; ͬ����һ��ԭʼ����IP�������һ��IP��Ƭ�� */
-
-/* CHN : ��ַ���Ͷ���, ��ͨ������ addr_type_to_string() ת���ַ�����ʽ. */
-/* ENG : address type, transform to string mode by call addr_type_to_string(). */
-enum addr_type_t{
- __ADDR_TYPE_INIT = 0,
- ADDR_TYPE_IPV4, /* 1, struct stream_tuple4_v4 */
- ADDR_TYPE_IPV6, /* 2, struct stream_tuple4_v6 */
- ADDR_TYPE_VLAN, /* 3 */
- ADDR_TYPE_MAC, /* 4 */
- ADDR_TYPE_ARP = 5, /* 5 */
- ADDR_TYPE_GRE, /* 6 */
- ADDR_TYPE_MPLS, /* 7 */
- ADDR_TYPE_PPPOE_SES, /* 8 */
- ADDR_TYPE_TCP, /* 9 */
- ADDR_TYPE_UDP = 10, /* 10 */
- ADDR_TYPE_L2TP, /* 11 */
- __ADDR_TYPE_IP_PAIR_V4, /* 12, ipv4 layer in tunnel mode */
- __ADDR_TYPE_IP_PAIR_V6, /* 13, ipv6 layer in tunnel mode */
- ADDR_TYPE_PPP, /* 14 */
- ADDR_TYPE_PPTP, /* 15 */
- ADDR_TYPE_MAC_IN_MAC, /* 16 */
- ADDR_TYPE_GPRS_TUNNEL, /* 17 */
- __ADDR_TYPE_MAX, /* 18 */
-};
-
-#define TCP_TAKEOVER_STATE_FLAG_OFF 0
-#define TCP_TAKEOVER_STATE_FLAG_ON 1
-
-
-/* CHN : Ӧ�ò㿴��������״̬���� */
-/* ENG : stream state for protocol or business plug*/
-#define OP_STATE_PENDING 0
-#define OP_STATE_REMOVE_ME 1
-#define OP_STATE_CLOSE 2
-#define OP_STATE_DATA 3
-
-/* CHN : Ӧ�ò㷵�ؽ������ */
-/* ENG : return value of plug */
-#define APP_STATE_GIVEME 0x00
-#define APP_STATE_DROPME 0x01
-#define APP_STATE_FAWPKT 0x00
-#define APP_STATE_DROPPKT 0x10
-
-/* CHN : �������Ͷ��� */
-/* ENG : stream type */
-enum stream_type_t{
- STREAM_TYPE_NON = 0, /* No stream concept indeed, such as vlan, IP, etc.; �����ĸ���, ��VLAN, IP��� */
- STREAM_TYPE_TCP,
- STREAM_TYPE_UDP, /* there is no stream of UDP in RFC, but in MESA platform, we build a UDP stream with same tuple4 packet */
- STREAM_TYPE_VLAN,
- STREAM_TYPE_SOCKS4,
- STREAM_TYPE_SOCKS5,
- STREAM_TYPE_HTTP_PROXY,
- STREAM_TYPE_PPPOE,
- STREAM_TYPE_L2TP,
- STREAM_TYPE_OPENVPN,
- STREAM_TYPE_PPTP,
- STREAM_TYPE_ISAKMP,
-};
-
-/*
- CHN: ���ĵײ������������,
- ��ͬ��stream_type_t, ���統ǰ��ΪSTREAM_TYPE_TCP, ���ײ��������Ϳ�����STREAM_TUNNLE_PPTP.
- ��Ϊ���������Ƕ��ֲ�ͬ����Ƕ�����, ֻ��¼��ײ�(��MAC�������)��������.
-*/
-enum stream_carry_tunnel_t{
- STREAM_TUNNLE_NON = 0, /* default is 0, not tunnel; Ĭ��Ϊ0, ������; */
- STREAM_TUNNLE_6OVER4 = 1 << 0,
- STREAM_TUNNLE_4OVER6 = 1 << 1,
- STREAM_TUNNLE_GRE = 1 << 2,
- STREAM_TUNNLE_IP_IN_IP = 1 << 3,
- STREAM_TUNNLE_PPTP = 1 << 4,
- STREAM_TUNNLE_L2TP = 1 << 5,
- STREAM_TUNNLE_TEREDO = 1 << 6,
- STREAM_TUNNEL_GPRS_TUNNEL = 1 << 7,
-};
-
-typedef struct raw_ipfrag_list{
- void *frag_packet;
- int pkt_len;
- int type; /* IPv4 or IPv6 */
- struct raw_ipfrag_list *next;
-}raw_ipfrag_list_t;
-
-
-#ifndef STRUCT_TUPLE4_DEFINED
-#define STRUCT_TUPLE4_DEFINED (1)
-/* compat for start, papp; ����start, papp */
-struct tuple4 {
- u_int saddr;
- u_int daddr;
- u_short source;
- u_short dest;
-};
-#endif
-
-struct tuple6
-{
- UCHAR saddr[16] ;
- UCHAR daddr[16] ;
- UINT16 source;
- UINT16 dest;
-};
-
-/* network-order */
-struct stream_tuple4_v4{
- UINT32 saddr; /* network order */
- UINT32 daddr; /* network order */
- UINT16 source; /* network order */
- UINT16 dest; /* network order */
-};
-
-
-#ifndef IPV6_ADDR_LEN
-#define IPV6_ADDR_LEN (sizeof(struct in6_addr))
-#endif
-
-struct stream_tuple4_v6
-{
- UCHAR saddr[IPV6_ADDR_LEN] ;
- UCHAR daddr[IPV6_ADDR_LEN] ;
- UINT16 source; /* network order */
- UINT16 dest; /* network order */
-};
-
-
-#define GRE_TAG_LEN (4)
-struct layer_addr_gre
-{
- UINT16 call_id; /* network order */
-};
-
-
-#define VLAN_ID_MASK (0x0FFF)
-#define VLAN_TAG_LEN (4)
-struct layer_addr_vlan
-{
- UINT16 vlan_id; /* network order */
-};
-
-#define VLAN_ID_LEN 4
-struct tuplevlan
-{
- UCHAR vlan_id[VLAN_ID_LEN];
-};
-
-struct layer_addr_pppoe_session
-{
-#if __BYTE_ORDER == __LITTLE_ENDIAN
- unsigned int ver:4;
- unsigned int type:4;
-#elif __BYTE_ORDER == __BIG_ENDIAN
- unsigned int type:4;
- unsigned int ver:4;
-#endif
- unsigned char code;
- unsigned short session_id;
-};
-
-#ifndef MAC_ADDR_LEN
-#define MAC_ADDR_LEN (6)
-#endif
-
-struct layer_addr_mac
-{
- UCHAR dst_mac[MAC_ADDR_LEN]; /* network order */
- UCHAR src_mac[MAC_ADDR_LEN]; /* network order */
-};
-
-struct layer_addr_ipv4
-{
- UINT32 saddr; /* network order */
- UINT32 daddr; /* network order */
- /* 2014-04-21 lijia add,
- Ϊ�˽�Լ�ڴ�ռ䡢�ʹ���Ч��, ��ǿ�ư�Э���δ���,
- IP���TCP����Ϊһ����,
- �����������IP, �˿���ϢΪ0;
- */
- UINT16 source; /* network order */
- UINT16 dest; /* network order */
-};
-
-struct layer_addr_ipv6
-{
- UCHAR saddr[IPV6_ADDR_LEN] ; /* network order */
- UCHAR daddr[IPV6_ADDR_LEN] ; /* network order */
- /* 2014-04-21 lijia add,
- Ϊ�˽�Լ�ڴ�ռ䡢�ʹ���Ч��, ��ǿ�ư�Э���δ���,
- IP���TCP����Ϊһ����,
- �����������IP, �˿���ϢΪ0;
- */
- UINT16 source;/* network order */
- UINT16 dest;/* network order */
-};
-
-struct layer_addr_tcp
-{
- UINT16 source; /* network order */
- UINT16 dest; /* network order */
-};
-
-struct layer_addr_udp
-{
- UINT16 source; /* network order */
- UINT16 dest; /* network order */
-};
-
-
-struct layer_addr_l2tp_v2_t{
- UINT16 tunnelid_C2S; /* network order, �Դ���㴴�����ķ���Ϊ׼ */
- UINT16 tunnelid_S2C; /* network order, �Դ���㴴�����ķ���Ϊ׼ */
- UINT16 sessionid_C2S; /* network order, �Դ���㴴�����ķ���Ϊ׼ */
- UINT16 sessionid_S2C; /* network order, �Դ���㴴�����ķ���Ϊ׼ */
-};
-
-struct layer_addr_l2tp_v3_t{
- UINT32 sessionlid; /* network order */
-};
-
-struct layer_addr_l2tp
-{
- UCHAR version; /* v2 or v3 */
- union
- {
- struct layer_addr_l2tp_v2_t l2tp_addr_v2;
- struct layer_addr_l2tp_v3_t l2tp_addr_v3;
- }l2tpun;
-};
-
-#define MAX_MPLS_ADDR_LAYER 4
-struct layer_addr_mpls
-{
- unsigned int src_mpls_pkt[MAX_MPLS_ADDR_LAYER];
- char src_mpls_layer_num;
- unsigned int dest_mpls_pkt[MAX_MPLS_ADDR_LAYER];
- char dest_mpls_layer_num;
-};
-
-struct layer_addr_pptp
-{
- UINT16 C2S_call_id; /* C2S�Դ����Э�鷽��Ϊ׼, TCP SYNΪC2S, UDPԴ�˿ڴ��ΪC2S, callid, network order */
- UINT16 S2C_call_id; /* S2Ck�Դ����Э�鷽��Ϊ׼, TCP SYN/ACKΪS2C, UDPĿ�Ķ˿ڴ��ΪS2C, callid, network order */
-};
-
-struct layer_addr_gtp
-{
- unsigned long long source; /* From Client */
- unsigned int src_seq;
- unsigned long long dest; /* From Server */
- unsigned int dest_seq;
-}__attribute__ ((aligned (1)));
-
-#define MAC_IN_MAC_HDR_LEN (sizeof(struct mesa_ethernet_hdr) + sizeof(struct mesa_ethernet_hdr))
-struct layer_addr_mac_in_mac
-{
- UCHAR outer_dst_mac[MAC_ADDR_LEN]; /* �����mac��ַ, network order */
- UCHAR outer_src_mac[MAC_ADDR_LEN]; /* �����mac��ַ, network order */
- UCHAR inner_dst_mac[MAC_ADDR_LEN]; /* �ڲ�mac��ַ, network order */
- UCHAR inner_src_mac[MAC_ADDR_LEN]; /* �ڲ�mac��ַ, network order */
-};
-
-struct layer_addr
-{
- UCHAR addrtype; /* definition in enum addr_type_t */
- UCHAR addrlen;
- UCHAR pkttype; /* packet special features, definition in MACRO PKT_TYPE_xxx */
- UCHAR pktipfragtype; /* ip frag packetfeatures, definition in MACRO PKT_TYPE_xxx */
-
- UCHAR __pad[4]; /* pad for alignment */
- union
- {
- struct stream_tuple4_v4 *tuple4_v4;
- struct stream_tuple4_v6 *tuple4_v6;
- struct layer_addr_ipv4 *ipv4;
- struct layer_addr_ipv6 *ipv6;
- struct layer_addr_vlan *vlan;
- struct layer_addr_mac *mac;
- struct layer_addr_gre *gre;
- struct layer_addr_tcp *tcp;
- struct layer_addr_udp *udp;
- struct layer_addr_pppoe_session *pppoe_ses;
- struct layer_addr_l2tp *l2tp;
- struct layer_addr_pptp *pptp;
- struct layer_addr_mac_in_mac *mimac;
- struct layer_addr_gtp *gtp;
- struct layer_addr_mpls *mpls;
-
- void *paddr;
- };
-
-};
-
-/* CHN : �����˽ṹ���ں�papp����, ����ָ��ʱ, ����struct layer_addrǿת */
-/* ENG : compat for papp, can be transform to struct layer_addr pointer */
-struct ipaddr
-{
- UCHAR addrtype; /* definition in enum addr_type_t */
- UCHAR addrlen;
- UCHAR pkttype; /* packet special features, definition in MACRO PKT_TYPE_xxx */
- UCHAR pktipfragtype; /* ip frag packetfeatures, definition in MACRO PKT_TYPE_xxx */
- UCHAR __pad[4]; /* pad for alignment */
- union
- {
- struct stream_tuple4_v4 *v4;
- struct stream_tuple4_v6 *v6;
- void *paddr;
- };
-
-};
-
-struct tcpdetail
-{
- void *pdata;
- UINT32 datalen;
- UINT32 lostlen; /* lost data len, not accumulated, current procedure */
- UINT32 serverpktnum; /* C2S, this value indicate TCP-ALL packet, include syn, ack, rst, if want get tcp data status, use stream_project.h : struct tcp_flow_stat */
- UINT32 clientpktnum; /* S2C, this value indicate TCP-ALL packet, include syn, ack, rst, if want get tcp data status, use stream_project.h : struct tcp_flow_stat */
- UINT32 serverbytes; /* C2S, this value indicate TCP-ALL packet, include syn, ack, rst, if want get tcp data status, use stream_project.h : struct tcp_flow_stat */
- UINT32 clientbytes; /* S2C, this value indicate TCP-ALL packet, include syn, ack, rst, if want get tcp data status, use stream_project.h : struct tcp_flow_stat */
- UINT64 createtime;
- UINT64 lastmtime;
-};
-
-struct udpdetail
-{
- void *pdata;
- UINT32 datalen;
- UINT32 pad;
- UINT32 serverpktnum; /* C2S, you should better use stream_project.h : struct udp_flow_stat */
- UINT32 clientpktnum; /* S2C, you should better use stream_project.h : struct udp_flow_stat */
- UINT32 serverbytes; /* C2S, you should better use stream_project.h : struct udp_flow_stat */
- UINT32 clientbytes; /* S2C, you should better use stream_project.h : struct udp_flow_stat */
- UINT64 createtime;
- UINT64 lastmtime;
-};
-
-struct streaminfo
-{
- struct layer_addr addr;
- struct streaminfo *pfather; /* this stream's carry layer stream; �ϲ����ṹ�� */
- UCHAR type; /* stream type, definition in enum stream_type_t */
- UCHAR threadnum;
- UCHAR dir; /* valid in all stream life, current stream direction state, 0x01:c-->s; 0x02:s-->c; 0x03 c<-->s; */
- UCHAR curdir; /* valid in current procedure, current packet direction, 0x01:c-->s; 0x02:s-->c */
- UCHAR opstate; /* stream state, definition in MACRO OP_STATE_xxx */
- UCHAR pktstate; /* for TCPALL plug, stream state, definition in MACRO OP_STATE_xxx */
- UCHAR routedir; /* network topology route direction, is valid in serial mode */
- UCHAR stream_state; /* stream management state, for example, in TCP stream, maybe SYN, DATA, NOUSE */
- UINT32 hash_index; /* stream hash index, maybe reduplicate with other stream when hash algorithm collide */
- UINT32 stream_index; /* stream global index per thread */
- union
- {
- struct tcpdetail *ptcpdetail;
- struct udpdetail *pudpdetail;
- void *pdetail;
- };
- };
-
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* CHN : �ڴ������غ���, ����ƽ̨�IJ������ʹ�ô��ຯ��������ͷ��ڴ� */
-/* ENG : memory management function, plugs must call these functions instead of malloc, free in <stdlib.h> */
-void *dictator_malloc(int thread_seq,size_t size);
-void dictator_free(int thread_seq,void *pbuf);
-void *dictator_realloc(int thread_seq, void* pbuf, size_t size);
-
-/* CHN : ��ȡ��ǰϵͳ���еIJ��������߳����� */
-/* ENG : get current total thread of platfomr */
-int get_thread_count(void);
-
-/* CHN : ����enum addr_type_tַ����ת���ɿɴ�ӡ���ַ�����ʽ */
-/* ENG : transform binary addr_type_t to string mode */
-const char *addr_type_to_string(enum addr_type_t type);
-
-/*
- ENG : transform tuple4 to string mode, must used in packet process thread context;
- CHN : ��layer_addr��ַת�����ַ�����ʽ, �������ڰ������߳�.
-*/
-const char *printaddr (const struct layer_addr *paddrinfo, int threadindex);
-
-/*
- ENG : a reentrant version of printaddr, thread safe;
- CHN : printaddr�Ŀ�����汾, ���̰߳�ȫ��.
-*/
-const char *printaddr_r(const struct layer_addr *paddrinfo, char *out_buf, int out_buf_len);
-
-
-/*
- ENG : transform layer address to string mode, must used in packet process thread context,
- the return value is read-only, user can't free it;
- CHN : ��layer_addr��ַת�����ַ�����ʽ, �������ڰ������߳�, ���ص�ָ��Ϊֻ��, ʹ���߲���free.
-*/
-const char *layer_addr_ntop(const struct streaminfo *pstream);
-
-/*
- ENG : a reentrant version of layer_addr_ntop, thread safe, return a pointer to the destination string 'out_buf';
- CHN : layer_addr_ntop_r�Ŀ�����汾, ���̰߳�ȫ��, ���ص�ָ��ִ��ʹ�����ṩ��out_buf, ���ڴ�����֯.
-*/
-char *layer_addr_ntop_r(const struct streaminfo *pstream, char *out_buf, int out_buf_len);
-
-/*
- ENG : transform layer type to abbr string mode, is reentrant, the return value is read-only, user can't free it;.
- CHN : ��layer_addr��ַ����ת������д�ַ�����ʽ, �������̰߳�ȫ, ���ص�ָ��Ϊֻ��, ʹ���߲���free..
-*/
-const char *layer_addr_prefix_ntop(const struct streaminfo *pstream);
-
-
-/*
- ENG : duplicate a same layer_addr struct, memory obtained with malloc(3);
- CHN : ����һ����ȫ��ͬ��layer_addr�ṹ��, �ڴ�ͨ��malloc(3)��ȡ.
-*/
-struct layer_addr * layer_addr_dup(const struct layer_addr *paddrinfo);
-
-/*
- ENG: used to free all memory of paddrinfo;
- CHN: �����ͷ�paddrinfo�ڴ�.
-*/
-void layer_addr_free(struct layer_addr *paddrinfo);
-
-
-/*
- ENG : duplicate a same streaminfo list, memory obtained with malloc(3);
- CHN : ����һ����ȫ��ͬ��streaminfo�ṹ�弰�����ṹ, �ڴ�ͨ��malloc(3)��ȡ.
-*/
-struct streaminfo *streaminfo_dup(const struct streaminfo *stream);
-
-/*
- ENG: used to free all memory of streaminfo;
- CHN: �����ͷŽṹ�弰�����ṹ���ڴ�.
-*/
-void streaminfo_free(struct streaminfo *stream);
-
-
-/*
- addr list transform function, like inet_ntop(), inet_pton(),
- use '<' as delimitation between layer,
- if direction is double, for ip, port, use '-' as delimitation between source and destination,
-
- for example:
- "T4T:6005-1673<IP4:61.147.112.53-11.215.62.23<MAC:0000ea60040d-0200000003b6"
-
- args:
- pstream : stream info;
- dst : buf to store result;
- size : dst buf's size;
- addr_list_str: addr list string;
- thread_index : thread index;
-
- ����ֵ:
- >0:ת����Ľ��ʵ��ռ���ڴ泤��, stream_addr_list_ntop()�������ַ���ĩβ��'\0';
- -1:dst����ռ䳤�Ȳ���;
- -2:��ʽ����;
- -3:��������;
-*/
-int stream_addr_list_ntop(const struct streaminfo *pstream, char *dst, int size);
-int stream_addr_list_pton(const char *addr_list_str, void *dst, int size, int thread_index);
-
-/*
- TCP,UDP��ģʽ��, ��ȡ��ǰIP����ԭʼ��Ƭ��.
-*/
-const raw_ipfrag_list_t *get_raw_frag_list(const struct streaminfo *stream);
-
-/*
- IP���ģʽ��, ��ȡ��ǰIP����ԭʼ��Ƭ��.
-*/
-const raw_ipfrag_list_t *ip_plug_get_raw_ipfrag_list(int thread_num, enum addr_type_t addr_type);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
+#ifndef _APP_STREAM_BASE_H_
+#define _APP_STREAM_BASE_H_
+
+#define STREAM_BASE_H_VERSION (20170616)
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef UINT8
+typedef unsigned char UINT8;
+#endif
+#ifndef UCHAR
+typedef unsigned char UCHAR;
+#endif
+#ifndef UINT16
+typedef unsigned short UINT16;
+#endif
+
+#ifndef UINT32
+typedef unsigned int UINT32;
+#endif
+#ifndef UINT64
+typedef unsigned long long UINT64;
+#endif
+
+/* CHN : ������� */
+/* ENG : stream direction definition*/
+#define DIR_C2S 0x01
+#define DIR_S2C 0x02
+#define DIR_DOUBLE 0x03
+
+/* CHN : ����ײ㴫�䷽����,����ģʽ������ */
+/* ENG : network topology route direction, is valid in serial mode */
+#define DIR_ROUTE_UP 0x00
+#define DIR_ROUTE_DOWN 0x01
+
+/* CHN : ���������Ͷ��� */
+/* ENG : single packet type definition */
+#define PKT_TYPE_NORMAL (0x0) /* normal, common */
+#define PKT_TYPE_IPREBUILD (1<<0) /* ip frag reassembled packet; ip��Ƭ���鱨�� */
+#define PKT_TYPE_TCPUNORDER (1<<1) /* TCP out of order packet; TCP������ */
+#define PKT_TYPE_TCPREORDER (1<<2) /* TCP sequential packet; TCP��������õ����ݰ� */
+#define PKT_TYPE_TCPRETRANS (1<<3) /* TCP retransmit packet; TCP�ش����� */
+#define PKT_TYPE_IP_FRAG (1<<4) /* IP frag packet; IP��Ƭ�� */
+#define PKT_TYPE_IP_FRAG_LAST (1<<5) /* last IP frag packet; ͬ����һ��ԭʼ����IP�������һ��IP��Ƭ�� */
+
+/* CHN : ��ַ���Ͷ���, ��ͨ������ addr_type_to_string() ת���ַ�����ʽ. */
+/* ENG : address type, transform to string mode by call addr_type_to_string(). */
+enum addr_type_t{
+ __ADDR_TYPE_INIT = 0,
+ ADDR_TYPE_IPV4, /* 1, struct stream_tuple4_v4 */
+ ADDR_TYPE_IPV6, /* 2, struct stream_tuple4_v6 */
+ ADDR_TYPE_VLAN, /* 3 */
+ ADDR_TYPE_MAC, /* 4 */
+ ADDR_TYPE_ARP = 5, /* 5 */
+ ADDR_TYPE_GRE, /* 6 */
+ ADDR_TYPE_MPLS, /* 7 */
+ ADDR_TYPE_PPPOE_SES, /* 8 */
+ ADDR_TYPE_TCP, /* 9 */
+ ADDR_TYPE_UDP = 10, /* 10 */
+ ADDR_TYPE_L2TP, /* 11 */
+ __ADDR_TYPE_IP_PAIR_V4, /* 12, ipv4 layer in tunnel mode */
+ __ADDR_TYPE_IP_PAIR_V6, /* 13, ipv6 layer in tunnel mode */
+ ADDR_TYPE_PPP, /* 14 */
+ ADDR_TYPE_PPTP, /* 15 */
+ ADDR_TYPE_MAC_IN_MAC, /* 16 */
+ ADDR_TYPE_GPRS_TUNNEL, /* 17 */
+ __ADDR_TYPE_MAX, /* 18 */
+};
+
+#define TCP_TAKEOVER_STATE_FLAG_OFF 0
+#define TCP_TAKEOVER_STATE_FLAG_ON 1
+
+
+/* CHN : Ӧ�ò㿴��������״̬���� */
+/* ENG : stream state for protocol or business plug*/
+#define OP_STATE_PENDING 0
+#define OP_STATE_REMOVE_ME 1
+#define OP_STATE_CLOSE 2
+#define OP_STATE_DATA 3
+
+/* CHN : Ӧ�ò㷵�ؽ������ */
+/* ENG : return value of plug */
+#define APP_STATE_GIVEME 0x00
+#define APP_STATE_DROPME 0x01
+#define APP_STATE_FAWPKT 0x00
+#define APP_STATE_DROPPKT 0x10
+
+/* CHN : �������Ͷ��� */
+/* ENG : stream type */
+enum stream_type_t{
+ STREAM_TYPE_NON = 0, /* No stream concept indeed, such as vlan, IP, etc.; �����ĸ���, ��VLAN, IP��� */
+ STREAM_TYPE_TCP,
+ STREAM_TYPE_UDP, /* there is no stream of UDP in RFC, but in MESA platform, we build a UDP stream with same tuple4 packet */
+ STREAM_TYPE_VLAN,
+ STREAM_TYPE_SOCKS4,
+ STREAM_TYPE_SOCKS5,
+ STREAM_TYPE_HTTP_PROXY,
+ STREAM_TYPE_PPPOE,
+ STREAM_TYPE_L2TP,
+ STREAM_TYPE_OPENVPN,
+ STREAM_TYPE_PPTP,
+ STREAM_TYPE_ISAKMP,
+};
+
+/*
+ CHN: ���ĵײ������������,
+ ��ͬ��stream_type_t, ���統ǰ��ΪSTREAM_TYPE_TCP, ���ײ��������Ϳ�����STREAM_TUNNLE_PPTP.
+ ��Ϊ���������Ƕ��ֲ�ͬ����Ƕ�����, ֻ��¼��ײ�(��MAC�������)��������.
+*/
+enum stream_carry_tunnel_t{
+ STREAM_TUNNLE_NON = 0, /* default is 0, not tunnel; Ĭ��Ϊ0, ������; */
+ STREAM_TUNNLE_6OVER4 = 1 << 0,
+ STREAM_TUNNLE_4OVER6 = 1 << 1,
+ STREAM_TUNNLE_GRE = 1 << 2,
+ STREAM_TUNNLE_IP_IN_IP = 1 << 3,
+ STREAM_TUNNLE_PPTP = 1 << 4,
+ STREAM_TUNNLE_L2TP = 1 << 5,
+ STREAM_TUNNLE_TEREDO = 1 << 6,
+ STREAM_TUNNEL_GPRS_TUNNEL = 1 << 7,
+ STREAM_TUNNEL_MULTI_MAC = 1 << 8,
+};
+
+typedef struct raw_ipfrag_list{
+ void *frag_packet;
+ int pkt_len;
+ int type; /* IPv4 or IPv6 */
+ struct raw_ipfrag_list *next;
+}raw_ipfrag_list_t;
+
+
+#ifndef STRUCT_TUPLE4_DEFINED
+#define STRUCT_TUPLE4_DEFINED (1)
+/* compat for start, papp; ����start, papp */
+struct tuple4 {
+ u_int saddr;
+ u_int daddr;
+ u_short source;
+ u_short dest;
+};
+#endif
+
+struct tuple6
+{
+ UCHAR saddr[16] ;
+ UCHAR daddr[16] ;
+ UINT16 source;
+ UINT16 dest;
+};
+
+/* network-order */
+struct stream_tuple4_v4{
+ UINT32 saddr; /* network order */
+ UINT32 daddr; /* network order */
+ UINT16 source; /* network order */
+ UINT16 dest; /* network order */
+};
+
+
+#ifndef IPV6_ADDR_LEN
+#define IPV6_ADDR_LEN (sizeof(struct in6_addr))
+#endif
+
+struct stream_tuple4_v6
+{
+ UCHAR saddr[IPV6_ADDR_LEN] ;
+ UCHAR daddr[IPV6_ADDR_LEN] ;
+ UINT16 source; /* network order */
+ UINT16 dest; /* network order */
+};
+
+
+#define GRE_TAG_LEN (4)
+struct layer_addr_gre
+{
+ UINT16 call_id; /* network order */
+};
+
+
+#define VLAN_ID_MASK (0x0FFF)
+#define VLAN_TAG_LEN (4)
+struct layer_addr_vlan
+{
+ UINT16 vlan_id; /* network order */
+};
+
+#define VLAN_ID_LEN 4
+struct tuplevlan
+{
+ UCHAR vlan_id[VLAN_ID_LEN];
+};
+
+struct layer_addr_pppoe_session
+{
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int ver:4;
+ unsigned int type:4;
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int type:4;
+ unsigned int ver:4;
+#endif
+ unsigned char code;
+ unsigned short session_id;
+};
+
+#ifndef MAC_ADDR_LEN
+#define MAC_ADDR_LEN (6)
+#endif
+
+struct layer_addr_mac
+{
+ UCHAR dst_mac[MAC_ADDR_LEN]; /* network order */
+ UCHAR src_mac[MAC_ADDR_LEN]; /* network order */
+};
+
+struct layer_addr_ipv4
+{
+ UINT32 saddr; /* network order */
+ UINT32 daddr; /* network order */
+ /* 2014-04-21 lijia add,
+ Ϊ�˽�Լ�ڴ�ռ䡢�ʹ���Ч��, ��ǿ�ư�Э���δ���,
+ IP���TCP����Ϊһ����,
+ �����������IP, �˿���ϢΪ0;
+ */
+ UINT16 source; /* network order */
+ UINT16 dest; /* network order */
+};
+
+struct layer_addr_ipv6
+{
+ UCHAR saddr[IPV6_ADDR_LEN] ; /* network order */
+ UCHAR daddr[IPV6_ADDR_LEN] ; /* network order */
+ /* 2014-04-21 lijia add,
+ Ϊ�˽�Լ�ڴ�ռ䡢�ʹ���Ч��, ��ǿ�ư�Э���δ���,
+ IP���TCP����Ϊһ����,
+ �����������IP, �˿���ϢΪ0;
+ */
+ UINT16 source;/* network order */
+ UINT16 dest;/* network order */
+};
+
+struct layer_addr_tcp
+{
+ UINT16 source; /* network order */
+ UINT16 dest; /* network order */
+};
+
+struct layer_addr_udp
+{
+ UINT16 source; /* network order */
+ UINT16 dest; /* network order */
+};
+
+
+struct layer_addr_l2tp_v2_t{
+ UINT16 tunnelid_C2S; /* network order, �Դ���㴴�����ķ���Ϊ׼ */
+ UINT16 tunnelid_S2C; /* network order, �Դ���㴴�����ķ���Ϊ׼ */
+ UINT16 sessionid_C2S; /* network order, �Դ���㴴�����ķ���Ϊ׼ */
+ UINT16 sessionid_S2C; /* network order, �Դ���㴴�����ķ���Ϊ׼ */
+};
+
+struct layer_addr_l2tp_v3_t{
+ UINT32 sessionlid; /* network order */
+};
+
+struct layer_addr_l2tp
+{
+ UCHAR version; /* v2 or v3 */
+ union
+ {
+ struct layer_addr_l2tp_v2_t l2tp_addr_v2;
+ struct layer_addr_l2tp_v3_t l2tp_addr_v3;
+ }l2tpun;
+};
+
+#define MAX_MPLS_ADDR_LAYER 4
+struct layer_addr_mpls
+{
+ unsigned int src_mpls_pkt[MAX_MPLS_ADDR_LAYER];
+ char src_mpls_layer_num;
+ unsigned int dest_mpls_pkt[MAX_MPLS_ADDR_LAYER];
+ char dest_mpls_layer_num;
+};
+
+struct layer_addr_pptp
+{
+ UINT16 C2S_call_id; /* C2S�Դ����Э�鷽��Ϊ׼, TCP SYNΪC2S, UDPԴ�˿ڴ��ΪC2S, callid, network order */
+ UINT16 S2C_call_id; /* S2Ck�Դ����Э�鷽��Ϊ׼, TCP SYN/ACKΪS2C, UDPĿ�Ķ˿ڴ��ΪS2C, callid, network order */
+};
+
+struct layer_addr_gtp
+{
+ unsigned long long source; /* From Client */
+ unsigned int src_seq;
+ unsigned long long dest; /* From Server */
+ unsigned int dest_seq;
+}__attribute__ ((aligned (1)));
+
+#define MAC_IN_MAC_HDR_LEN (sizeof(struct mesa_ethernet_hdr) + sizeof(struct mesa_ethernet_hdr))
+struct layer_addr_mac_in_mac
+{
+ UCHAR outer_dst_mac[MAC_ADDR_LEN]; /* �����mac��ַ, network order */
+ UCHAR outer_src_mac[MAC_ADDR_LEN]; /* �����mac��ַ, network order */
+ UCHAR inner_dst_mac[MAC_ADDR_LEN]; /* �ڲ�mac��ַ, network order */
+ UCHAR inner_src_mac[MAC_ADDR_LEN]; /* �ڲ�mac��ַ, network order */
+};
+
+struct layer_addr
+{
+ UCHAR addrtype; /* definition in enum addr_type_t */
+ UCHAR addrlen;
+ UCHAR pkttype; /* packet special features, definition in MACRO PKT_TYPE_xxx */
+ UCHAR pktipfragtype; /* ip frag packetfeatures, definition in MACRO PKT_TYPE_xxx */
+
+ UCHAR __pad[4]; /* pad for alignment */
+ union
+ {
+ struct stream_tuple4_v4 *tuple4_v4;
+ struct stream_tuple4_v6 *tuple4_v6;
+ struct layer_addr_ipv4 *ipv4;
+ struct layer_addr_ipv6 *ipv6;
+ struct layer_addr_vlan *vlan;
+ struct layer_addr_mac *mac;
+ struct layer_addr_gre *gre;
+ struct layer_addr_tcp *tcp;
+ struct layer_addr_udp *udp;
+ struct layer_addr_pppoe_session *pppoe_ses;
+ struct layer_addr_l2tp *l2tp;
+ struct layer_addr_pptp *pptp;
+ struct layer_addr_mac_in_mac *mimac;
+ struct layer_addr_gtp *gtp;
+ struct layer_addr_mpls *mpls;
+
+ void *paddr;
+ };
+
+};
+
+/* CHN : �����˽ṹ���ں�papp����, ����ָ��ʱ, ����struct layer_addrǿת */
+/* ENG : compat for papp, can be transform to struct layer_addr pointer */
+struct ipaddr
+{
+ UCHAR addrtype; /* definition in enum addr_type_t */
+ UCHAR addrlen;
+ UCHAR pkttype; /* packet special features, definition in MACRO PKT_TYPE_xxx */
+ UCHAR pktipfragtype; /* ip frag packetfeatures, definition in MACRO PKT_TYPE_xxx */
+ UCHAR __pad[4]; /* pad for alignment */
+ union
+ {
+ struct stream_tuple4_v4 *v4;
+ struct stream_tuple4_v6 *v6;
+ void *paddr;
+ };
+
+};
+
+struct tcpdetail
+{
+ void *pdata;
+ UINT32 datalen;
+ UINT32 lostlen; /* lost data len, not accumulated, current procedure */
+ UINT32 serverpktnum; /* C2S, this value indicate TCP-ALL packet, include syn, ack, rst, if want get tcp data status, use stream_project.h : struct tcp_flow_stat */
+ UINT32 clientpktnum; /* S2C, this value indicate TCP-ALL packet, include syn, ack, rst, if want get tcp data status, use stream_project.h : struct tcp_flow_stat */
+ UINT32 serverbytes; /* C2S, this value indicate TCP-ALL packet, include syn, ack, rst, if want get tcp data status, use stream_project.h : struct tcp_flow_stat */
+ UINT32 clientbytes; /* S2C, this value indicate TCP-ALL packet, include syn, ack, rst, if want get tcp data status, use stream_project.h : struct tcp_flow_stat */
+ UINT64 createtime;
+ UINT64 lastmtime;
+};
+
+struct udpdetail
+{
+ void *pdata;
+ UINT32 datalen;
+ UINT32 pad;
+ UINT32 serverpktnum; /* C2S, you should better use stream_project.h : struct udp_flow_stat */
+ UINT32 clientpktnum; /* S2C, you should better use stream_project.h : struct udp_flow_stat */
+ UINT32 serverbytes; /* C2S, you should better use stream_project.h : struct udp_flow_stat */
+ UINT32 clientbytes; /* S2C, you should better use stream_project.h : struct udp_flow_stat */
+ UINT64 createtime;
+ UINT64 lastmtime;
+};
+
+struct streaminfo
+{
+ struct layer_addr addr;
+ struct streaminfo *pfather; /* this stream's carry layer stream; �ϲ����ṹ�� */
+ UCHAR type; /* stream type, definition in enum stream_type_t */
+ UCHAR threadnum;
+ UCHAR dir; /* valid in all stream life, current stream direction state, 0x01:c-->s; 0x02:s-->c; 0x03 c<-->s; */
+ UCHAR curdir; /* valid in current procedure, current packet direction, 0x01:c-->s; 0x02:s-->c */
+ UCHAR opstate; /* stream state, definition in MACRO OP_STATE_xxx */
+ UCHAR pktstate; /* for TCPALL plug, stream state, definition in MACRO OP_STATE_xxx */
+ UCHAR routedir; /* network topology route direction, is valid in serial mode */
+ UCHAR stream_state; /* stream management state, for example, in TCP stream, maybe SYN, DATA, NOUSE */
+ UINT32 hash_index; /* stream hash index, maybe reduplicate with other stream when hash algorithm collide */
+ UINT32 stream_index; /* stream global index per thread */
+ union
+ {
+ struct tcpdetail *ptcpdetail;
+ struct udpdetail *pudpdetail;
+ void *pdetail;
+ };
+ };
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* CHN : �ڴ������غ���, ����ƽ̨�IJ������ʹ�ô��ຯ��������ͷ��ڴ� */
+/* ENG : memory management function, plugs must call these functions instead of malloc, free in <stdlib.h> */
+void *dictator_malloc(int thread_seq,size_t size);
+void dictator_free(int thread_seq,void *pbuf);
+void *dictator_realloc(int thread_seq, void* pbuf, size_t size);
+
+/* CHN : ��ȡ��ǰϵͳ���еIJ��������߳����� */
+/* ENG : get current total thread of platfomr */
+int get_thread_count(void);
+
+/* CHN : ����enum addr_type_tַ����ת���ɿɴ�ӡ���ַ�����ʽ */
+/* ENG : transform binary addr_type_t to string mode */
+const char *addr_type_to_string(enum addr_type_t type);
+
+/*
+ ENG : transform tuple4 to string mode, must used in packet process thread context;
+ CHN : ��layer_addr��ַת�����ַ�����ʽ, �������ڰ������߳�.
+*/
+const char *printaddr (const struct layer_addr *paddrinfo, int threadindex);
+
+/*
+ ENG : a reentrant version of printaddr, thread safe;
+ CHN : printaddr�Ŀ�����汾, ���̰߳�ȫ��.
+*/
+const char *printaddr_r(const struct layer_addr *paddrinfo, char *out_buf, int out_buf_len);
+
+
+/*
+ ENG : transform layer address to string mode, must used in packet process thread context,
+ the return value is read-only, user can't free it;
+ CHN : ��layer_addr��ַת�����ַ�����ʽ, �������ڰ������߳�, ���ص�ָ��Ϊֻ��, ʹ���߲���free.
+*/
+const char *layer_addr_ntop(const struct streaminfo *pstream);
+
+/*
+ ENG : a reentrant version of layer_addr_ntop, thread safe, return a pointer to the destination string 'out_buf';
+ CHN : layer_addr_ntop_r�Ŀ�����汾, ���̰߳�ȫ��, ���ص�ָ��ִ��ʹ�����ṩ��out_buf, ���ڴ�����֯.
+*/
+char *layer_addr_ntop_r(const struct streaminfo *pstream, char *out_buf, int out_buf_len);
+
+/*
+ ENG : transform layer type to abbr string mode, is reentrant, the return value is read-only, user can't free it;.
+ CHN : ��layer_addr��ַ����ת������д�ַ�����ʽ, �������̰߳�ȫ, ���ص�ָ��Ϊֻ��, ʹ���߲���free..
+*/
+const char *layer_addr_prefix_ntop(const struct streaminfo *pstream);
+
+
+/*
+ ENG : duplicate a same layer_addr struct, memory obtained with malloc(3);
+ CHN : ����һ����ȫ��ͬ��layer_addr�ṹ��, �ڴ�ͨ��malloc(3)��ȡ.
+*/
+struct layer_addr * layer_addr_dup(const struct layer_addr *paddrinfo);
+
+/*
+ ENG: used to free all memory of paddrinfo;
+ CHN: �����ͷ�paddrinfo�ڴ�.
+*/
+void layer_addr_free(struct layer_addr *paddrinfo);
+
+
+/*
+ ENG : duplicate a same streaminfo list, memory obtained with malloc(3);
+ CHN : ����һ����ȫ��ͬ��streaminfo�ṹ�弰�����ṹ, �ڴ�ͨ��malloc(3)��ȡ.
+*/
+struct streaminfo *streaminfo_dup(const struct streaminfo *stream);
+
+/*
+ ENG: used to free all memory of streaminfo;
+ CHN: �����ͷŽṹ�弰�����ṹ���ڴ�.
+*/
+void streaminfo_free(struct streaminfo *stream);
+
+
+/*
+ addr list transform function, like inet_ntop(), inet_pton(),
+ use '<' as delimitation between layer,
+ if direction is double, for ip, port, use '-' as delimitation between source and destination,
+
+ for example:
+ "T4T:6005-1673<IP4:61.147.112.53-11.215.62.23<MAC:0000ea60040d-0200000003b6"
+
+ args:
+ pstream : stream info;
+ dst : buf to store result;
+ size : dst buf's size;
+ addr_list_str: addr list string;
+ thread_index : thread index;
+
+ ����ֵ:
+ >0:ת����Ľ��ʵ��ռ���ڴ泤��, stream_addr_list_ntop()�������ַ���ĩβ��'\0';
+ -1:dst����ռ䳤�Ȳ���;
+ -2:��ʽ����;
+ -3:��������;
+*/
+int stream_addr_list_ntop(const struct streaminfo *pstream, char *dst, int size);
+int stream_addr_list_pton(const char *addr_list_str, void *dst, int size, int thread_index);
+
+/*
+ TCP,UDP��ģʽ��, ��ȡ��ǰIP����ԭʼ��Ƭ��.
+*/
+const raw_ipfrag_list_t *get_raw_frag_list(const struct streaminfo *stream);
+
+/*
+ IP���ģʽ��, ��ȡ��ǰIP����ԭʼ��Ƭ��.
+*/
+const raw_ipfrag_list_t *ip_plug_get_raw_ipfrag_list(int thread_num, enum addr_type_t addr_type);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/include/stream_internal.h b/include/stream_internal.h
index d08be2b..d9f070e 100644
--- a/include/stream_internal.h
+++ b/include/stream_internal.h
@@ -1,353 +1,356 @@
-#ifndef _APP_STREAM_INTERNAL_H_
-#define _APP_STREAM_INTERNAL_H_
-
-#include "stream_inc/stream_base.h"
-#include "stream_inc/stream_project.h"
-#include "stream_inc/stream_proxy.h"
-#include "stream_inc/stream_tunnel.h"
-#include "stream_register.h"
-#include "stream_custom.h"
-#include "stream_inc/stream_inject.h"
-#include "stream_inc/stream_rawpkt.h"
-#include "stream_inc/stream_control.h"
-#include "net/mesa_net.h"
-#include "sysinfo.h"
-#include "MESA_handle_logger.h"
-
-#define STREAM_BASE_MD5_CHECK "dd09b3b11993cc835200db477dad7d4b"
-#define STREAM_CONTROL_MD5_CHECK "75aab0821e489b84355fa22ad02a2e78"
-#define STREAM_ENTRY_MD5_CHECK "7dab86d65114ebe5438e85e0d008645d"
-#define STREAM_INJECT_MD5_CHECK "1e25b7a8cd812db2ad261264b6783d64"
-#define STREAM_PROJECT_MD5_CHECK "fc2b981f7e2c99e73d8857e206cb4977"
-#define STREAM_PROXY_MD5_CHECK "25cec664c9b44a8cac29f6e3e117eaa6"
-#define STREAM_RAWPKT_MD5_CHECK "48fdc3294bced1c74a853e197db8fd67"
-#define STREAM_TUNNEL_MD5_CHECK "d20aa6b4f5683b7b0040676547997be0"
-
-#define IP_PORT_UNION_VERSION (1) /* �Ƿ�IP-PORT�ϲ� */
-#define COMPAT_PAPP_FOR_BENCHMARK (0) /* 2015-01-07 lijia add, ͬpapp�ԱȽ��ʱ, ��ʱ�ر�Ƕ�ס���������Э��, ����һ�� */
-#define USE_RBTREE_INSTEAD_LIST (0) /* ��HASH��ͻʱ, ʹ�ú������������, ������������±��� */
-#define USE_LINUX_KERNEL_HASH_ALGO (1) /* ʹ��LINUX�ں�HASH�㷨 */
-
-#define SAPP_INSECTICIDE (0) /* ɱ��(DEBUG)��ʱ����, ������Ī�������BUGʱ��ʱ����, ���緢������, �����糬�� */
-
-//#define CYCLE_PKT_DUMP (1 && DEBUG) /* 2015-04-16 lijia add, ������������޹�coredump, ���Ҳ���ԭ�� */
-#define CYCLE_PKT_DUMP (1) /* 2015-04-16 lijia add, ������������޹�coredump, ���Ҳ���ԭ�� */
-
-#define PCAP_CAP_FROM_IP (0) /* Ϊ��ģ��pag�����߻���, ��pcapҲģ���IPv4ͷ����ʼ��ȡ */
-
-#ifndef likely
-#define likely(x) __builtin_expect(!!(x), 1)
-#endif
-
-#ifndef unlikely
-#define unlikely(x) __builtin_expect(!!(x), 0)
-#endif
-
-#ifndef offsetof
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-#endif
-
-#ifndef container_of
-#define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
-#endif
-
-#define sapp_get_struct_header(ptr, type, member) container_of(ptr, type, member)
-
-#define RAW_PKT_MAGIC_NUM (0xF1E2D3C4) /* 1:���ڼ��ݾ���Ŀ, ��call_old��������ݽṹʱ,ʶ��ԭʼ������Դ; 2:��ȫ�Լ�� */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* ԭʼ���ṹ */
-typedef struct {
- unsigned int magic_num;
- int offset_to_raw_pkt_hdr; /* ����ص���Ӧ��������raw_pkt_data��ƫ���� */
- enum addr_type_t low_layer_type; /* ԭʼ����ײ�Э�������, ������MAC(pcap����), Ҳ������IPv4(pag����) */
- int __lib_raw_pkt_len; /* �ײ㲶�����ṩ�İ���ʵԭʼ���� */
- int raw_pkt_len; /* ���ϲ�Ӧ�ÿ���ԭʼ���ܳ���, �п��ܲ�����ʵ��, ����������Ethernet�� */
- unsigned int hd_hash; /* ����Ӳ���������Ԫ��HASH, ����ƽ̨CPU�������� */
- const void *__lib_raw_pkt_data; /* �ײ㲶�����ṩ����ʵԭʼ��ָ�� */
- const void *raw_pkt_data; /* ���ϲ�Ӧ�ÿ���ԭʼ��ͷָ��, �п���������Ethernet��, ����low_layer_type�ж�Э������ */
- struct timeval raw_pkt_ts; /* ԭʼ������ʱ���, ���ȫΪ0��֧�ִ˹���(��pagģʽ) */
- const void *io_lib_pkt_reference; /* ���õײ�I/O���ԭʼ�������ṹ, ����:����marsio��˵, ���ײ��mbuf�ṹ */
-}raw_pkt_t;
-
-
-struct buf_unorder
-{
- struct buf_unorder *next;
- struct buf_unorder *prev;
- //void *data;
- //UINT32 len;
- void *this_ip_hdr; /* ������Դ����ʵԭʼ��, Ҳ������Դ�������IP��Ƭ��,��'ip_reassemble_pkt'���� */
- struct mesa_tcp_hdr *this_tcp_hdr;
- void *tcpdata; /* TCP�����ݲ���ָ��, ����TCPͷ */
- UINT16 tcpdatalen; /* TCP�����ݲ��ֳ��� */
- UINT16 urg_ptr;
- char fin;
- char urg;
- char rst;
- unsigned char ip_reassemble_pkt;
- UINT32 seq;
- UINT32 ack;
- raw_ipfrag_list_t *ipfrag_list; /* �����ǰ����IP��Ƭ����İ�, ��Ҫ�洢����IP��Ƭ������ */
- raw_pkt_t raw_pkt; /* ������洢ԭʼ�� */
-};
-
-/*�����ṹ�嶨�壺*/
-struct half_tcpstream
-{
- UCHAR *data;
- UINT32 offset; /*data�е�һ���ֽ���TCP�������е�ƫ����*/
- UINT32 count; /*�����ӽ���������Ϊֹ������������ܳ����ֽ���*/
- UINT32 count_new; /*�����µ��������ֽ���*/
- UINT32 count_ideal; /*�����ӽ���������Ϊֹ��������Ӧ�õ���������ܳ���*/
- UINT32 pktcout; /*�����ۼƵ���İ�����, �����ش���, ACK, ������SYN */
- UINT32 totallost; /*�����ۼƶ�������*/
- UINT32 seq; /*���������ڴ���seq���*/
- UINT32 first_data_seq; /*����������ʼ�ĵ�seq���*/
-
- //UINT32 ack_seq; /*�����������ʹ�õ�Ӧ���, 2017-08-02 lijia modify , �ƶ���struct tcpdetail_private */
-
- UINT16 window; /*�������ݻ������ڴ�С*/
- UCHAR __pad__;
- UCHAR finstate; /*fin״̬*/
- UINT16 unorder_cnt;/* 2014-11-27 lijia modify, ijЩ���������޴�, UCHAR�Ͳ���, ��չΪUINT16 */
- UINT16 maxunorder; /* 2014-11-27 lijia modify, ijЩ���������޴�, UCHAR�Ͳ���, ��չΪUINT16 */
- struct buf_unorder *unorderlist; /*�����������*/
- struct buf_unorder *unorderlisttail; /*�����������β��ָ��*/
-};
-
-struct streaminfo_private
-{
- /* ����ṹ�����ڽṹ����ǰ, ָ���ַ���Ի���ǿת */
- struct streaminfo stream_public;
- /* ���±���Ϊƽ̨�ڲ�˽��, ���ⲻ�ɼ� */
- void *pproject; //ÿ�����̿����Զ���ʹ�ã�
-
- /* ---8 bytes-- */
- UCHAR layer_dir:2; /* ������Ч, ��ǰ��ĵ�ַ�Ƿ��Ĭ�Ϲ���"��˿��ǿͻ���"��ͬ */
- UCHAR stream_dir:2; /* ��������������Ч, ���Ĵ洢�ĵ�ַ�Ƿ��Ĭ�Ϲ���"��˿��ǿͻ���"��ͬ */
- UCHAR addr_use_as_hash:1; /* �����addr�Ƿ���ΪHASH����ͱȽϵIJ���, ��:MAC��ַ��������� */
- UCHAR addr_skip_for_layer_cmp:1;/*�����addr�Ƿ���Ϊ��ַ�ȽϵIJ㼶���磺MPLS��ַ����Ϊ�������㣬ֱ����������ֵĬ��Ϊ0������Ҫ�Ƚ�*/
- UCHAR need_update_opposite_addr:1;/*�����addr�Ƿ��ڶԲ�����ʱ���£��磺MPLS��ǩ�ǶԳ�ʱ��Ҫ��S2C���һ������¼�����ǩ,��ֵĬ��Ϊ0��������Ҫ����*/
- UCHAR stream_killed_flag:1; /* 2014-08-22 lijia add, ����ģʽ��, �Ѿ������Kill, ֮�������ֱ��Drop��Kill, �����ٸ��ϲ��� */
- UCHAR dirreverse; /* ��������ʱ�Ƿ������ip��ַ��ת, ����"��˿��ǿͻ���"�����෴ */
- UINT16 timeout;/* ÿ�����ӵĶ��г�ʱʱ��, ��ֵ��������;, 1:���ھ�����̭��ʱ���ް��������, �Խ�Լ�ڴ�; 2:���ڱ�����ʱ���ް�����, ����IM�೤ʱ���ް������Ӳ�δ����, �����ýϴ��timeout */
- unsigned short offset_to_raw_pkt_hdr; /* ����ͷ�����ԭʼ������ʼ��ַ��ƫ���� */
- unsigned short offset_to_ip_hdr; /* 2015-12-07 lijia add, UDP/TCP ��ͷ����ڳ��ص�IP��ͷƫ���� */
- /* ===8 bytes=== */
- const raw_pkt_t *raw_pkt; /* 2014-12-30 lijia add, ��Щ�ص�������֧��ԭʼ��, ����������Ҫ, �洢��private�ṹ�� */
-
- /* ---8 bytes-- */
- unsigned int hash_slave; /* 2015-12-14 lijia add, ʹ��linux_jhash����ʱ, ����ͬʱ�õ��������ϵ�HASHֵ, ��HASH����ȷ����HASH����SLOTλ��, slave_HASH���ڿ��ٱȽϵ�ַ�Ƿ���� */
- unsigned char hash_not_head_times;/* 2015-12-15 lijia add, ��ǰindex����HASH SLOT�ĵ�һλ�Ĵ��� */
- unsigned char cur_layer_raw_hdr_len; /* 2017-10-31 lijia add, ��ǰ���ԭʼ����ַ����, ��pppͷ��ѹ��, ԭ���汾�޷��������״̬, ����ʱҲ�޷���֪��ַ������ */
- char __pad;
- unsigned char gdev_block_timer;
- /* ===8 bytes=== */
-
- /* ---8 bytes-- */
- unsigned short stream_low_layer_tunnel_type; /* 2016-07-25 lijia add, ��¼�����ײ���������, 0Ϊ������, �������:enum stream_carry_tunnel_t */
- unsigned short stream_carry_up_layer_tunnel_type; /* ��ǰ���ϲ����������, ���統ǰ��ΪUDP, ���صĿ�����teredo������L2TP���� */
- /* 2016-07-08 lijia add, for janus hijack, ��Ӧ�ô洢��half_stream, �����յ�SYNʱ, ��û�д���half_streamʵ��, �����ݴ���streaminfo_private */
- unsigned short syn_opt_num;
- unsigned short synack_opt_num;
- /* ===8 bytes=== */
-
- struct tcp_option *syn_opt_array;
- struct tcp_option *synack_opt_array;
-};
-
-struct tcpdetail_private
-{
- /* ����ṹ�����ڽṹ����ǰ, ָ���ַ���Ի���ǿת */
- struct tcpdetail tcpdetail_public;
-
- /* ---8 bytes-- */
- UCHAR multisynflag:2; // multi syn
- UCHAR ignore_rst_fin:2;//������rst, fin����, ֻ����ʱ��lru����
- UCHAR needackflag:2; //��Ҫ�ϴ�ack����
- UCHAR takeoverflag:2;
- UCHAR tcpstateflag; // ���ڼ�¼tcp�ĻỰSYN���״̬
- UCHAR link_state; // ���ӵ�״̬
- UCHAR creat_mod;
- UINT16 tcpoverlen; // modify by lqy 20150225, ��¼��ǰ������һ�������ص�tcp���ȣ�
- UINT16 pad;
- /* ===8 bytes=== */
-
- struct half_tcpstream *pclient; //��client��TCP������Ϣ
- struct half_tcpstream *pserver; //�� server��TCP������Ϣ
- UINT32 iserverseq; //���ӽ���ʱ��ʱ�洢seq, ��ֵ��C2S->SYN+1
- UINT32 iclientseq; //���ӽ���ʱ��ʱ�洢seq, ��ֵ��S2C->SYN+1
- /* NOTE:
- ��first_ack_seq������half_tcpstream��?
- ��half_tcpstream�����յ���һ�����и��صİ��ŷ����,
- �����tcp_deal_ack()����������, �����S2C����, ��ô��һ��S2C���ݰ�����ʱ, �Ѿ�����first_ack_seq��.
- �����Է�ֹDDOS����.
- */
- UINT32 C2S_first_ack_seq; /* 2017-08-02 lijia modify, C2S���һ��ACK��, ��half_tcpstream->ack_seqһ����Լ�����������Բ���������� */
- UINT32 C2S_ack_seq; /* 2017-08-02 lijia add, C2S�൱ǰ��ACK�� */
- UINT32 S2C_first_ack_seq; /* 2017-08-02 lijia modify, C2S���һ��ACK��, ��half_tcpstream->ack_seqһ����Լ�����������Բ���������� */
- UINT32 S2C_ack_seq; /* 2017-08-02 lijia add, S2C�൱ǰ��ACK�� */
- void *apme; //Ӧ�ò�������
- 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���; �Լ������������, �Զ�Ӧ���յ������� */
-};
-
-struct udpdetail_private
-{
- /* ����ṹ�����ڽṹ����ǰ, ָ���ַ���Ի���ǿת */
- struct udpdetail udpdetail_public;
- void *apme; //Ӧ�ò�������
- struct udp_flow_stat *flow_stat; /* 2015-12-28 lijia add, udpdetail�е���ϸ����(64bit), ʵ���ڴ������ͷ���projectģ�����, ����ΪNULL */
-};
-
-/* 2015-02-26 lijia add, for stream-addr-list ntop, pton */
-typedef struct{
- struct streaminfo stream;
- char addr_value[MAX_ADDR_BIN_VALUE_LEN]; /* Ϊ��paddr������malloc, �������, ��stream����׷��һ�黺�� */
-}addr_continuous_bin_t;
-
-typedef struct{
- enum addr_type_t addr_type_bin;
- UCHAR stream_type;/* ����ʶ��ADDR_TYPE_IPV4��TCP����UDP */
- const char *addr_type_str;
- const char *addr_type_prefix;
- const char *addr_type_prefix_with_delim; /* ���ָ�����ǰ׺, ���ڱȽ��ַ���, ��ֹIPv4��IPv4_TCP�ַ����Ƚ�ʱ����, �����IPv4:, IPv4_TCP:�Ͳ����ڻ������� */
- int (*addr_n2p_fun)(const struct layer_addr *paddr, char *buf, int buf_len);
- int (*addr_p2n_fun)(char *addr_str, addr_continuous_bin_t *addr_bin_val);
-}addr_convert_t;
-
-struct pptp_stream_key{
- UINT32 sip; /* TCP-SYN����ԴIP, ����ǰ�data������, ����pptp->message_type�ж�, REQ���������ԴIP��Ϊ��sip */
- UINT32 dip; /* sip,dip are network order */
- UINT16 sip_side_call_id; /* �������ݰ�����sip������GRE����callid, ʵ�������ʾpeer call id, network order */
- UINT16 dip_side_call_id; /* �������ݰ�����dip������GRE����callid, ʵ�������ʾpeer call id, network order */
- //struct streaminfo_private *stream_pr; /* TODO 1, ���ڱ����ַ����, Ŀǰ��������ײ��IP��call_id */
-};
-
-/* PPTPЭ�����������ṹ, sapp�ڲ�ʹ�� */
-struct pptp_info_pri{
- struct MESA_tunnel_info tunnel_context;
- struct pptp_stream_key pptp_key;
- stSessionInfo ssinfo; /* ����ҵ�����������Ϣ */
- void *biz_pme; /* ҵ����Զ������� */
- struct streaminfo *my_stream; /* pptp�ײ�UDP�� */
- unsigned char threadnum;
- char insert_hash_flag; /* ���������ѽ�key����HASH�� */
- char content_notify_biz_flag; /* �Ƿ��Ѿ����ù�ҵ����, ��֮content_type */
-};
-
-/* ˽��pptp��ַ, pptp_addr�ṩ��ҵ����, ����gre_layer_len����FDʱ����ʶ�𱾲�ͷ������ */
-struct layer_addr_pptp_pri{
- struct layer_addr_pptp pptp_addr;
- int gre_layer_len;
-};
-
-struct l2tp_stream_key{
- UINT32 sip; /* L2TP�����������𷽵�IP, ����������SCCRQ, ICRQ, SCCCN�Ȱ���ԴIP, network order */
- UINT32 dip; /* L2TP�����������˵�IP, network order */
- UINT16 sport; /* network order */
- UINT16 dport; /* network order */
- UINT16 sip_side_tunnel_id; /* sip�ⷢ������tunnelid, network order */
- UINT16 sip_side_session_id; /* sip�ⷢ������tunnelid, network order */
- UINT16 dip_side_tunnel_id; /* dip�ⷢ������tunnelid, network order */
- UINT16 dip_side_session_id; /* dip�ⷢ������tunnelid, network order */
- //struct streaminfo_private *stream_pr; /* TODO 1, ���ڱ����ַ����, Ŀǰ��������ײ��IP��call_id */
-};
-
-struct l2tp_info_pri{
- struct MESA_tunnel_info tunnel_context;
- struct l2tp_stream_key l2tp_key;
- stSessionInfo ssinfo; /* ����ҵ��������� */
- void *biz_pme;
- const struct streaminfo *my_stream; /* l2tp�ײ�UDP�� */
- unsigned char thread_seq;
- char content_notify_biz_flag; /* �Ƿ��Ѿ����ù�ҵ����, ��֮content_type */
-};
-
-#define STATSD_SEND_MSS (1472)
-/* ȫ��Ψһ��ȫ�ֱ���, ͨ���ǿ�����������, �򲻳��仯��ȫ�ֱ���, ����������, ������ֻ�� */
-struct sapp_global_single_t{
- int signal_take_over_sw; /* �Ƿ�ӹܳ���ϵͳ�ź�, ��SIGSEGV, SIGABRT�ȵ� */
- int ipentry_priority_over_ipfrag; /* IP_entry���ȼ�����IP_frag_entry, Ĭ��Ϊ0, ��ӦWY�����ض����� */
- int kill_tcp_with_gdev; /* FDδ��Чʱ, ����gdev�������� */
- int cfg_send_tcp_offload_sw; /* ��������MTUʱ, ������Ƭ�ɶ��С��MTU�İ����� */
- int cfg_kill_tcp_rst_num; /* kill_tcp����rst������ */
- int cfg_kill_tcp_rst_signature; /* kill_tcp���͵�rst�Ƿ���Ҫָ����Ϣ, ����ʶ�� */
-
- void *fs2_handle;
- const char *fs2_server_ip;
- unsigned short fs2_server_port_host;
- short __pad1;
- int fs2_filed_id_array[COUNTER_NUM];
-
- int send_fake_pkt_mode; /* 2018-10-26 lijia add, for PanGu, ����ȱ��FD·��, ����ô���GDEV����rst��, DNS-fake����,mode 0�� Э��ջ���㷢���� 1��Э��ջ���㷢����3��gdevע�뷢������ģʽ��send_fake_pkt_gdev_sport��Ч */
- int send_fake_pkt_gdev_sport; /* 2018-10-26 lijia add, for PanGu, ����ѡ��vxlanԴ�˿� */
- int send_fake_pkt_sip;
- int treat_vlan_as_mac_in_mac_sw; /* MAC_IN_MAC���ᱻЭ��ջ��Ϊvlan��, ���߲���debug�ܲ�����, ���Ӵ�����, ǿ�ƽ�vlan����ΪMAC_IN_MAC��ʽ���� */
-
- int create_mpls_anyway;/*��������MAC��IP��֮�䴴��MPLS��*/
-
-};
-
-#define TIMESTAMP_SINGLE_PKT_REGION (4) /* ������ʱͳ������ */
-#define TIMESTAMP_SINGLE_PKT_REGION_MAX (5) /* ��������ͳ�������ֵ */
-typedef struct{
- unsigned int runtime_pkt_max_delay; /* �����������ʱ */
- unsigned long long pkt_total_num[TIMESTAMP_SINGLE_PKT_REGION_MAX]; /* ��¼��������ʱ���ܰ���, ������ͳ�� */
- unsigned long long pkt_total_time; /* ���һ��ʱ�������ʱ, ���ڼ���ƽ������������ʱ */
-}timestamp_record_region_t;
-
-
-/* ���߳�ȫ�ֱ���, �������ݰ�ͳ����Ϣ, ͨ��ֵ��ʵʱ�仯 */
-struct sapp_global_mthread_t{
- int ipv6_pkt_type_flag; /* ipv6 packet type, normal, or rebuild */
- int pptp_hash_max_search_times;
- int l2tp_hash_max_search_times;
- char __pad1[4];
- double pptp_hash_avg_search_times;
- double l2tp_hash_avg_search_times;
- int tcp_stream_special_timeout_num; /* ���õ�����ʱʱ�����, Ĭ�ϲ�����������������10% */
- int udp_stream_special_timeout_num;/* ���õ�����ʱʱ�����, Ĭ�ϲ�����������������10% */
- timestamp_record_region_t runtime_record;
- char __pad2__[32];
-};
-
-extern struct sapp_global_single_t sapp_global_single;
-extern struct sapp_global_mthread_t sapp_global_mthread[MAX_THREAD_NUM];
-
-extern int G_SKIP_NOT_IP_LAYER;
-extern int g_sapp_log_level;
-extern void *g_sapp_log_handle;
-
-#define sapp_runtime_log(log_level, format, args...) do{if(log_level>=g_sapp_log_level){MESA_handle_runtime_log(g_sapp_log_handle, log_level, "sapp", format, ##args);}}while(0)
-
-
-int MESA_kill_tcp_remedy(struct streaminfo *stream, const void *ext_raw_pkt);
-
-long long sapp_get_cpu_cycle(void);
-
-int get_stream_carry_tunnel_type(const struct streaminfo *this_stream, const struct streaminfo *upper_stream, unsigned short *tunnel_type);
-
-void cycle_pkt_dump(int thread_seq, const raw_pkt_t *p_raw_pkt);
-
-char biz_retval_to_platform(char biz_ret);
-char plat_state_to_biz(char plat_state);
-
-void idle_polling_call(int thread_seq);
-int gdev_block_send_rule(const struct streaminfo *pstream);
-int gdev_block_init(void);
- long long sapp_get_cpu_cycle(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
+#ifndef _APP_STREAM_INTERNAL_H_
+#define _APP_STREAM_INTERNAL_H_
+
+#include "stream_inc/stream_base.h"
+#include "stream_inc/stream_project.h"
+#include "stream_inc/stream_proxy.h"
+#include "stream_inc/stream_tunnel.h"
+#include "stream_register.h"
+#include "stream_custom.h"
+#include "stream_inc/stream_inject.h"
+#include "stream_inc/stream_rawpkt.h"
+#include "stream_inc/stream_control.h"
+#include "net/mesa_net.h"
+#include "sysinfo.h"
+#include "MESA_handle_logger.h"
+
+//#define STREAM_BASE_MD5_CHECK "dd09b3b11993cc835200db477dad7d4b"
+//#define STREAM_CONTROL_MD5_CHECK "75aab0821e489b84355fa22ad02a2e78"
+//#define STREAM_ENTRY_MD5_CHECK "7dab86d65114ebe5438e85e0d008645d"
+//#define STREAM_INJECT_MD5_CHECK "1e25b7a8cd812db2ad261264b6783d64"
+//#define STREAM_PROJECT_MD5_CHECK "fc2b981f7e2c99e73d8857e206cb4977"
+//#define STREAM_PROXY_MD5_CHECK "25cec664c9b44a8cac29f6e3e117eaa6"
+//#define STREAM_RAWPKT_MD5_CHECK "48fdc3294bced1c74a853e197db8fd67"
+//#define STREAM_TUNNEL_MD5_CHECK "d20aa6b4f5683b7b0040676547997be0"
+
+#define IP_PORT_UNION_VERSION (1) /* �Ƿ�IP-PORT�ϲ� */
+#define COMPAT_PAPP_FOR_BENCHMARK (0) /* 2015-01-07 lijia add, ͬpapp�ԱȽ��ʱ, ��ʱ�ر�Ƕ�ס���������Э��, ����һ�� */
+#define USE_RBTREE_INSTEAD_LIST (0) /* ��HASH��ͻʱ, ʹ�ú������������, ������������±��� */
+#define USE_LINUX_KERNEL_HASH_ALGO (1) /* ʹ��LINUX�ں�HASH�㷨 */
+
+#define SAPP_INSECTICIDE (0) /* ɱ��(DEBUG)��ʱ����, ������Ī�������BUGʱ��ʱ����, ���緢������, �����糬�� */
+
+//#define CYCLE_PKT_DUMP (1 && DEBUG) /* 2015-04-16 lijia add, ������������޹�coredump, ���Ҳ���ԭ�� */
+#define CYCLE_PKT_DUMP (1) /* 2015-04-16 lijia add, ������������޹�coredump, ���Ҳ���ԭ�� */
+
+#define PCAP_CAP_FROM_IP (0) /* Ϊ��ģ��pag�����߻���, ��pcapҲģ���IPv4ͷ����ʼ��ȡ */
+
+#ifndef likely
+#define likely(x) __builtin_expect(!!(x), 1)
+#endif
+
+#ifndef unlikely
+#define unlikely(x) __builtin_expect(!!(x), 0)
+#endif
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+#ifndef container_of
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+#endif
+
+#define sapp_get_struct_header(ptr, type, member) container_of(ptr, type, member)
+
+#define RAW_PKT_MAGIC_NUM (0xF1E2D3C4) /* 1:���ڼ��ݾ���Ŀ, ��call_old��������ݽṹʱ,ʶ��ԭʼ������Դ; 2:��ȫ�Լ�� */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ԭʼ���ṹ */
+typedef struct {
+ unsigned int magic_num;
+ int offset_to_raw_pkt_hdr; /* ����ص���Ӧ��������raw_pkt_data��ƫ���� */
+ enum addr_type_t low_layer_type; /* ԭʼ����ײ�Э�������, ������MAC(pcap����), Ҳ������IPv4(pag����) */
+ int __lib_raw_pkt_len; /* �ײ㲶�����ṩ�İ���ʵԭʼ���� */
+ int raw_pkt_len; /* ���ϲ�Ӧ�ÿ���ԭʼ���ܳ���, �п��ܲ�����ʵ��, ����������Ethernet�� */
+ unsigned int hd_hash; /* ����Ӳ���������Ԫ��HASH, ����ƽ̨CPU�������� */
+ const void *__lib_raw_pkt_data; /* �ײ㲶�����ṩ����ʵԭʼ��ָ�� */
+ const void *raw_pkt_data; /* ���ϲ�Ӧ�ÿ���ԭʼ��ͷָ��, �п���������Ethernet��, ����low_layer_type�ж�Э������ */
+ struct timeval raw_pkt_ts; /* ԭʼ������ʱ���, ���ȫΪ0��֧�ִ˹���(��pagģʽ) */
+ const void *io_lib_pkt_reference; /* ���õײ�I/O���ԭʼ�������ṹ, ����:����marsio��˵, ���ײ��mbuf�ṹ */
+}raw_pkt_t;
+
+
+struct buf_unorder
+{
+ struct buf_unorder *next;
+ struct buf_unorder *prev;
+ //void *data;
+ //UINT32 len;
+ void *this_ip_hdr; /* ������Դ����ʵԭʼ��, Ҳ������Դ�������IP��Ƭ��,��'ip_reassemble_pkt'���� */
+ struct mesa_tcp_hdr *this_tcp_hdr;
+ void *tcpdata; /* TCP�����ݲ���ָ��, ����TCPͷ */
+ UINT16 tcpdatalen; /* TCP�����ݲ��ֳ��� */
+ UINT16 urg_ptr;
+ char fin;
+ char urg;
+ char rst;
+ unsigned char ip_reassemble_pkt;
+ UINT32 seq;
+ UINT32 ack;
+ raw_ipfrag_list_t *ipfrag_list; /* �����ǰ����IP��Ƭ����İ�, ��Ҫ�洢����IP��Ƭ������ */
+ raw_pkt_t raw_pkt; /* ������洢ԭʼ�� */
+};
+
+/*�����ṹ�嶨�壺*/
+struct half_tcpstream
+{
+ UCHAR *data;
+ UINT32 offset; /*data�е�һ���ֽ���TCP�������е�ƫ����*/
+ UINT32 count; /*�����ӽ���������Ϊֹ������������ܳ����ֽ���*/
+ UINT32 count_new; /*�����µ��������ֽ���*/
+ UINT32 count_ideal; /*�����ӽ���������Ϊֹ��������Ӧ�õ���������ܳ���*/
+ UINT32 pktcout; /*�����ۼƵ���İ�����, �����ش���, ACK, ������SYN */
+ UINT32 totallost; /*�����ۼƶ�������*/
+ UINT32 seq; /*���������ڴ���seq���*/
+ UINT32 first_data_seq; /*����������ʼ�ĵ�seq���*/
+
+ //UINT32 ack_seq; /*�����������ʹ�õ�Ӧ���, 2017-08-02 lijia modify , �ƶ���struct tcpdetail_private */
+
+ UINT16 window; /*�������ݻ������ڴ�С*/
+ UCHAR __pad__;
+ UCHAR finstate; /*fin״̬*/
+ UINT16 unorder_cnt;/* 2014-11-27 lijia modify, ijЩ���������޴�, UCHAR�Ͳ���, ��չΪUINT16 */
+ UINT16 maxunorder; /* 2014-11-27 lijia modify, ijЩ���������޴�, UCHAR�Ͳ���, ��չΪUINT16 */
+ struct buf_unorder *unorderlist; /*�����������*/
+ struct buf_unorder *unorderlisttail; /*�����������β��ָ��*/
+};
+
+struct streaminfo_private
+{
+ /* ����ṹ�����ڽṹ����ǰ, ָ���ַ���Ի���ǿת */
+ struct streaminfo stream_public;
+ /* ���±���Ϊƽ̨�ڲ�˽��, ���ⲻ�ɼ� */
+ void *pproject; //ÿ�����̿����Զ���ʹ�ã�
+
+ /* ---8 bytes-- */
+ UCHAR layer_dir:2; /* ������Ч, ��ǰ��ĵ�ַ�Ƿ��Ĭ�Ϲ���"��˿��ǿͻ���"��ͬ */
+ UCHAR stream_dir:2; /* ��������������Ч, ���Ĵ洢�ĵ�ַ�Ƿ��Ĭ�Ϲ���"��˿��ǿͻ���"��ͬ */
+ UCHAR addr_use_as_hash:1; /* �����addr�Ƿ���ΪHASH����ͱȽϵIJ���, ��:MAC��ַ��������� */
+ UCHAR addr_skip_for_layer_cmp:1;/*�����addr�Ƿ���Ϊ��ַ�ȽϵIJ㼶���磺MPLS��ַ����Ϊ�������㣬ֱ����������ֵĬ��Ϊ0������Ҫ�Ƚ�*/
+ UCHAR need_update_opposite_addr:1;/*�����addr�Ƿ��ڶԲ�����ʱ���£��磺MPLS��ǩ�ǶԳ�ʱ��Ҫ��S2C���һ������¼�����ǩ,��ֵĬ��Ϊ0��������Ҫ����*/
+ UCHAR stream_killed_flag:1; /* 2014-08-22 lijia add, ����ģʽ��, �Ѿ������Kill, ֮�������ֱ��Drop��Kill, �����ٸ��ϲ��� */
+ UCHAR dirreverse; /* ��������ʱ�Ƿ������ip��ַ��ת, ����"��˿��ǿͻ���"�����෴ */
+ UINT16 timeout;/* ÿ�����ӵĶ��г�ʱʱ��, ��ֵ��������;, 1:���ھ�����̭��ʱ���ް��������, �Խ�Լ�ڴ�; 2:���ڱ�����ʱ���ް�����, ����IM�೤ʱ���ް������Ӳ�δ����, �����ýϴ��timeout */
+ unsigned short offset_to_raw_pkt_hdr; /* ����ͷ�����ԭʼ������ʼ��ַ��ƫ���� */
+ unsigned short offset_to_ip_hdr; /* 2015-12-07 lijia add, UDP/TCP ��ͷ����ڳ��ص�IP��ͷƫ���� */
+ /* ===8 bytes=== */
+ const raw_pkt_t *raw_pkt; /* 2014-12-30 lijia add, ��Щ�ص�������֧��ԭʼ��, ����������Ҫ, �洢��private�ṹ�� */
+
+ /* ---8 bytes-- */
+ unsigned int hash_slave; /* 2015-12-14 lijia add, ʹ��linux_jhash����ʱ, ����ͬʱ�õ��������ϵ�HASHֵ, ��HASH����ȷ����HASH����SLOTλ��, slave_HASH���ڿ��ٱȽϵ�ַ�Ƿ���� */
+ unsigned char hash_not_head_times;/* 2015-12-15 lijia add, ��ǰindex����HASH SLOT�ĵ�һλ�Ĵ��� */
+ unsigned char cur_layer_raw_hdr_len; /* 2017-10-31 lijia add, ��ǰ���ԭʼ����ַ����, ��pppͷ��ѹ��, ԭ���汾�޷��������״̬, ����ʱҲ�޷���֪��ַ������ */
+ char __pad;
+ unsigned char gdev_block_timer;
+ /* ===8 bytes=== */
+
+ /* ---8 bytes-- */
+ unsigned short stream_low_layer_tunnel_type; /* 2016-07-25 lijia add, ��¼�����ײ���������, 0Ϊ������, �������:enum stream_carry_tunnel_t */
+ unsigned short stream_carry_up_layer_tunnel_type; /* ��ǰ���ϲ����������, ���統ǰ��ΪUDP, ���صĿ�����teredo������L2TP���� */
+ /* 2016-07-08 lijia add, for janus hijack, ��Ӧ�ô洢��half_stream, �����յ�SYNʱ, ��û�д���half_streamʵ��, �����ݴ���streaminfo_private */
+ unsigned short syn_opt_num;
+ unsigned short synack_opt_num;
+ /* ===8 bytes=== */
+
+ struct tcp_option *syn_opt_array;
+ struct tcp_option *synack_opt_array;
+};
+
+struct tcpdetail_private
+{
+ /* ����ṹ�����ڽṹ����ǰ, ָ���ַ���Ի���ǿת */
+ struct tcpdetail tcpdetail_public;
+
+ /* ---8 bytes-- */
+ UCHAR multisynflag:2; // multi syn
+ UCHAR ignore_rst_fin:2;//������rst, fin����, ֻ����ʱ��lru����
+ UCHAR needackflag:2; //��Ҫ�ϴ�ack����
+ UCHAR takeoverflag:2;
+ UCHAR tcpstateflag; // ���ڼ�¼tcp�ĻỰSYN���״̬
+ UCHAR link_state; // ���ӵ�״̬
+ UCHAR creat_mod;
+ UINT16 tcpoverlen; // modify by lqy 20150225, ��¼��ǰ������һ�������ص�tcp���ȣ�
+ UINT16 pad;
+ /* ===8 bytes=== */
+
+ struct half_tcpstream *pclient; //��client��TCP������Ϣ
+ struct half_tcpstream *pserver; //�� server��TCP������Ϣ
+ UINT32 iserverseq; //���ӽ���ʱ��ʱ�洢seq, ��ֵ��C2S->SYN+1
+ UINT32 iclientseq; //���ӽ���ʱ��ʱ�洢seq, ��ֵ��S2C->SYN+1
+ /* NOTE:
+ ��first_ack_seq������half_tcpstream��?
+ ��half_tcpstream�����յ���һ�����и��صİ��ŷ����,
+ �����tcp_deal_ack()����������, �����S2C����, ��ô��һ��S2C���ݰ�����ʱ, �Ѿ�����first_ack_seq��.
+ �����Է�ֹDDOS����.
+ */
+ UINT32 C2S_first_ack_seq; /* 2017-08-02 lijia modify, C2S���һ��ACK��, ��half_tcpstream->ack_seqһ����Լ�����������Բ���������� */
+ UINT32 C2S_ack_seq; /* 2017-08-02 lijia add, C2S�൱ǰ��ACK�� */
+ UINT32 S2C_first_ack_seq; /* 2017-08-02 lijia modify, C2S���һ��ACK��, ��half_tcpstream->ack_seqһ����Լ�����������Բ���������� */
+ UINT32 S2C_ack_seq; /* 2017-08-02 lijia add, S2C�൱ǰ��ACK�� */
+ void *apme; //Ӧ�ò�������
+ 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���; �Լ������������, �Զ�Ӧ���յ������� */
+};
+
+struct udpdetail_private
+{
+ /* ����ṹ�����ڽṹ����ǰ, ָ���ַ���Ի���ǿת */
+ struct udpdetail udpdetail_public;
+ void *apme; //Ӧ�ò�������
+ struct udp_flow_stat *flow_stat; /* 2015-12-28 lijia add, udpdetail�е���ϸ����(64bit), ʵ���ڴ������ͷ���projectģ�����, ����ΪNULL */
+};
+
+/* 2015-02-26 lijia add, for stream-addr-list ntop, pton */
+typedef struct{
+ struct streaminfo stream;
+ char addr_value[MAX_ADDR_BIN_VALUE_LEN]; /* Ϊ��paddr������malloc, �������, ��stream����׷��һ�黺�� */
+}addr_continuous_bin_t;
+
+typedef struct{
+ enum addr_type_t addr_type_bin;
+ UCHAR stream_type;/* ����ʶ��ADDR_TYPE_IPV4��TCP����UDP */
+ const char *addr_type_str;
+ const char *addr_type_prefix;
+ const char *addr_type_prefix_with_delim; /* ���ָ�����ǰ׺, ���ڱȽ��ַ���, ��ֹIPv4��IPv4_TCP�ַ����Ƚ�ʱ����, �����IPv4:, IPv4_TCP:�Ͳ����ڻ������� */
+ int (*addr_n2p_fun)(const struct layer_addr *paddr, char *buf, int buf_len);
+ int (*addr_p2n_fun)(char *addr_str, addr_continuous_bin_t *addr_bin_val);
+}addr_convert_t;
+
+struct pptp_stream_key{
+ UINT32 sip; /* TCP-SYN����ԴIP, ����ǰ�data������, ����pptp->message_type�ж�, REQ���������ԴIP��Ϊ��sip */
+ UINT32 dip; /* sip,dip are network order */
+ UINT16 sip_side_call_id; /* �������ݰ�����sip������GRE����callid, ʵ�������ʾpeer call id, network order */
+ UINT16 dip_side_call_id; /* �������ݰ�����dip������GRE����callid, ʵ�������ʾpeer call id, network order */
+ //struct streaminfo_private *stream_pr; /* TODO 1, ���ڱ����ַ����, Ŀǰ��������ײ��IP��call_id */
+};
+
+/* PPTPЭ�����������ṹ, sapp�ڲ�ʹ�� */
+struct pptp_info_pri{
+ struct MESA_tunnel_info tunnel_context;
+ struct pptp_stream_key pptp_key;
+ stSessionInfo ssinfo; /* ����ҵ�����������Ϣ */
+ void *biz_pme; /* ҵ����Զ������� */
+ struct streaminfo *my_stream; /* pptp�ײ�UDP�� */
+ unsigned char threadnum;
+ char insert_hash_flag; /* ���������ѽ�key����HASH�� */
+ char content_notify_biz_flag; /* �Ƿ��Ѿ����ù�ҵ����, ��֮content_type */
+};
+
+/* ˽��pptp��ַ, pptp_addr�ṩ��ҵ����, ����gre_layer_len����FDʱ����ʶ�𱾲�ͷ������ */
+struct layer_addr_pptp_pri{
+ struct layer_addr_pptp pptp_addr;
+ int gre_layer_len;
+};
+
+struct l2tp_stream_key{
+ UINT32 sip; /* L2TP�����������𷽵�IP, ����������SCCRQ, ICRQ, SCCCN�Ȱ���ԴIP, network order */
+ UINT32 dip; /* L2TP�����������˵�IP, network order */
+ UINT16 sport; /* network order */
+ UINT16 dport; /* network order */
+ UINT16 sip_side_tunnel_id; /* sip�ⷢ������tunnelid, network order */
+ UINT16 sip_side_session_id; /* sip�ⷢ������tunnelid, network order */
+ UINT16 dip_side_tunnel_id; /* dip�ⷢ������tunnelid, network order */
+ UINT16 dip_side_session_id; /* dip�ⷢ������tunnelid, network order */
+ //struct streaminfo_private *stream_pr; /* TODO 1, ���ڱ����ַ����, Ŀǰ��������ײ��IP��call_id */
+};
+
+struct l2tp_info_pri{
+ struct MESA_tunnel_info tunnel_context;
+ struct l2tp_stream_key l2tp_key;
+ stSessionInfo ssinfo; /* ����ҵ��������� */
+ void *biz_pme;
+ const struct streaminfo *my_stream; /* l2tp�ײ�UDP�� */
+ unsigned char thread_seq;
+ char content_notify_biz_flag; /* �Ƿ��Ѿ����ù�ҵ����, ��֮content_type */
+};
+
+#define STATSD_SEND_MSS (1472)
+/* ȫ��Ψһ��ȫ�ֱ���, ͨ���ǿ�����������, �򲻳��仯��ȫ�ֱ���, ����������, ������ֻ�� */
+struct sapp_global_single_t{
+ int signal_take_over_sw; /* �Ƿ�ӹܳ���ϵͳ�ź�, ��SIGSEGV, SIGABRT�ȵ� */
+ int ipentry_priority_over_ipfrag; /* IP_entry���ȼ�����IP_frag_entry, Ĭ��Ϊ0, ��ӦWY�����ض����� */
+ int kill_tcp_with_gdev; /* FDδ��Чʱ, ����gdev�������� */
+ int cfg_send_tcp_offload_sw; /* ��������MTUʱ, ������Ƭ�ɶ��С��MTU�İ����� */
+ int cfg_kill_tcp_rst_num; /* kill_tcp����rst������ */
+ int cfg_kill_tcp_rst_signature; /* kill_tcp���͵�rst�Ƿ���Ҫָ����Ϣ, ����ʶ�� */
+
+ void *fs2_handle;
+ const char *fs2_server_ip;
+ unsigned short fs2_server_port_host;
+ short __pad1;
+ int fs2_filed_id_array[COUNTER_NUM];
+
+ int fs2_latency_id_array[COUNTER_NUM];
+
+
+ int send_fake_pkt_mode; /* 2018-10-26 lijia add, for PanGu, ����ȱ��FD·��, ����ô���GDEV����rst��, DNS-fake����,mode 0�� Э��ջ���㷢���� 1��Э��ջ���㷢����3��gdevע�뷢������ģʽ��send_fake_pkt_gdev_sport��Ч */
+ int send_fake_pkt_gdev_sport; /* 2018-10-26 lijia add, for PanGu, ����ѡ��vxlanԴ�˿� */
+ int send_fake_pkt_sip;
+ int treat_vlan_as_mac_in_mac_sw; /* MAC_IN_MAC���ᱻЭ��ջ��Ϊvlan��, ���߲���debug�ܲ�����, ���Ӵ�����, ǿ�ƽ�vlan����ΪMAC_IN_MAC��ʽ���� */
+
+ int create_mpls_anyway;/*��������MAC��IP��֮�䴴��MPLS��*/
+
+};
+
+#define TIMESTAMP_SINGLE_PKT_REGION (4) /* ������ʱͳ������ */
+#define TIMESTAMP_SINGLE_PKT_REGION_MAX (5) /* ��������ͳ�������ֵ */
+typedef struct{
+ unsigned int runtime_pkt_max_delay; /* �����������ʱ */
+ unsigned long long pkt_total_num[TIMESTAMP_SINGLE_PKT_REGION_MAX]; /* ��¼��������ʱ���ܰ���, ������ͳ�� */
+ unsigned long long pkt_total_time; /* ���һ��ʱ�������ʱ, ���ڼ���ƽ������������ʱ */
+}timestamp_record_region_t;
+
+
+/* ���߳�ȫ�ֱ���, �������ݰ�ͳ����Ϣ, ͨ��ֵ��ʵʱ�仯 */
+struct sapp_global_mthread_t{
+ int ipv6_pkt_type_flag; /* ipv6 packet type, normal, or rebuild */
+ int pptp_hash_max_search_times;
+ int l2tp_hash_max_search_times;
+ char __pad1[4];
+ double pptp_hash_avg_search_times;
+ double l2tp_hash_avg_search_times;
+ int tcp_stream_special_timeout_num; /* ���õ�����ʱʱ�����, Ĭ�ϲ�����������������10% */
+ int udp_stream_special_timeout_num;/* ���õ�����ʱʱ�����, Ĭ�ϲ�����������������10% */
+ timestamp_record_region_t runtime_record;
+ char __pad2__[32];
+};
+
+extern struct sapp_global_single_t sapp_global_single;
+extern struct sapp_global_mthread_t sapp_global_mthread[MAX_THREAD_NUM];
+
+extern int G_SKIP_NOT_IP_LAYER;
+extern int g_sapp_log_level;
+extern void *g_sapp_log_handle;
+
+#define sapp_runtime_log(log_level, format, args...) do{if(log_level>=g_sapp_log_level){MESA_handle_runtime_log(g_sapp_log_handle, log_level, "sapp", format, ##args);}}while(0)
+
+
+int MESA_kill_tcp_remedy(struct streaminfo *stream, const void *ext_raw_pkt);
+
+long long sapp_get_cpu_cycle(void);
+
+int get_stream_carry_tunnel_type(const struct streaminfo *this_stream, const struct streaminfo *upper_stream, unsigned short *tunnel_type);
+
+void cycle_pkt_dump(int thread_seq, const raw_pkt_t *p_raw_pkt);
+
+char biz_retval_to_platform(char biz_ret);
+char plat_state_to_biz(char plat_state);
+
+void idle_polling_call(int thread_seq);
+int gdev_block_send_rule(const struct streaminfo *pstream);
+int gdev_block_init(void);
+ long long sapp_get_cpu_cycle(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/inner_plug/sapp_assistant.cpp b/inner_plug/sapp_assistant.cpp
index 8cd4ed8..ab541a1 100644
--- a/inner_plug/sapp_assistant.cpp
+++ b/inner_plug/sapp_assistant.cpp
@@ -35,6 +35,8 @@ extern time_t g_CurrentTime;//add by lqy 20070606
extern time_t g_sapp_start_time;
extern volatile unsigned long long g_SysInputInfo[MAX_THREAD_NUM][COUNTER_NUM];
extern int g_packet_io_thread_num;
+extern char g_app_instance_name[64];
+
int sapp_assistant_version_VERSION_20181024;
extern int MESA_get_dev_ipv4(const char *device, int *ip_add);
@@ -359,6 +361,18 @@ static int sapp_fs2_init(void)
sapp_global_single.fs2_filed_id_array[SEND_TCP_SYN_ACK] = FS_register(sapp_global_single.fs2_handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "SEND_TCP_S/A");
sapp_global_single.fs2_filed_id_array[SEND_UDP_PKT] = FS_register(sapp_global_single.fs2_handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "SEND_UDP");
+ for(int i = 0; i < g_packet_io_thread_num; i++)
+ {
+ char histogram_name[16];
+ sprintf(histogram_name, "tid_%d(ns)", i);
+ sapp_global_single.fs2_latency_id_array[i] = FS_register_histogram(sapp_global_single.fs2_handle, //Field Stat���
+ FS_CALC_SPEED, //����ۼ�ֵ��˲ʱֵ
+ histogram_name, //ͳ�������ƣ��ַ���
+ 1, //��׷�ٵ���Сֵ
+ 100000000, //��׷�ٵ����ֵ
+ 2); //���ȣ���С�����λ����Χ1~4
+
+ }
FS_start(sapp_global_single.fs2_handle);
return 0;
@@ -421,6 +435,12 @@ void sapp_fs2_update(int field_index, unsigned long long value)
}
}
+void sapp_fs2_set_latency(int thead_seq, long long time_cost)
+{
+ if(sapp_global_single.fs2_handle != NULL){
+ FS_operate(sapp_global_single.fs2_handle, sapp_global_single.fs2_latency_id_array[thead_seq], 0, FS_OP_SET, time_cost);
+ }
+}
int sapp_assistant_init(void)
{
diff --git a/cmake-makefile b/makefile-cmake
index c8aae2e..c8aae2e 100644
--- a/cmake-makefile
+++ b/makefile-cmake
diff --git a/packet_io/packet_io.c b/packet_io/packet_io.c
index c5991da..5e6fe87 100644
--- a/packet_io/packet_io.c
+++ b/packet_io/packet_io.c
@@ -1,1318 +1,1325 @@
-#include "common_io_dll.h"
-#include "packet_io.h"
-#include "packet_io_internal.h"
-#include "stream_manage.h"
-#include "stream_internal.h"
-#include "mesa_net.h"
-#include "sendpacket.h"
-#include "iknow.h"
-#include <MESA/MESA_handle_logger.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <assert.h>
-#include <errno.h>
-#include <pthread.h>
-#include <sched.h>
-#include "MESA_feedback.h"
-
-/*
-2015-04-15
- ƽ̨ʵʱ������������ݰ�, ��sizeָ����С, �������100MB,
- ÿ���̷߳�Ϊ�����ļ�, ѭ��д��,
- �������:
- pid.thread_seq.[0-1].pcap,
-
- 0�ļ�����100MB��ֹͣ, ת����ʼд1�ļ�, 1�ļ�Ҳ����100MB��, ����������д0�ļ�.
-
- ͨ���ܿ��ؿ��ƴ˹����Ƿ���, ���鿴��ǰĿ¼�м���core, ��������д, ��ֹӲ����!
-
- debug_pkt_dump_switch=1
- debug_pkt_dump_max_num=5 //����core�ļ�
- debug_pkt_dump_max_size_per_thread=100 // ��λMB
-
- ����һ������, ��debug_pkt_dump,
-
- sapp��ʼ��ʱ���߳���, ����THREAD_NUM���ܵ�, Ȼ��fork����, �ӽ��̱�Ϊdebug_pkt_dump,
- �����̼�������sapp,
-
- ��mesa_default_pkt_cb������, ���յ��İ�ͨ���ܵ�����debug_pkt_dump����.
-
- debug_pkt_dump����, Ҳͬ������ͬ���߳�����������, д�ļ�.
-*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-int gdev_init(void);
-extern int packet_io_status_init(void);
-extern MESA_send_handle g_send_handle[MAX_THREAD_NUM];
-char g_send_dev_name[DEV_NAME_STR_LEN]; /* ���������� */
-unsigned char g_send_dev_mac[MAC_ADDR_LEN];
-unsigned char g_send_gateway_mac[MAC_ADDR_LEN]; /* ͨ���ֹ����û��ѯ·�ɱ���ARP���õ� */
-unsigned char g_send_gateway_mac_table[64][16][18];
-static int G_SND_ROUTE_INFO_NUM = 0;
-
-unsigned char g_send_gdev_ip_table[64][32];
-static int G_SND_GDEV_INFO_NUM = 0;
-
-char g_up_dev_name[DEV_NAME_STR_LEN]; /* ����ģʽĬ�ϲ������� */
-char g_down_dev_name[DEV_NAME_STR_LEN];
-//static char g_cap_filter[CAP_FILTER_STR_LEN];
-//static int g_cap_buf_queue_num = 10000; /* IO�̺߳ʹ����߳�֮��Ļ�����г��� */
-int g_topology_mode = NET_CONN_PARALLEL;
-int g_packet_io_cap_mode = CAP_MODEL_PCAP_ONLINE;
-int g_packet_io_cap_level = CAP_LEVEL_MAC; /* ������ʼλ��,Ĭ��MAC�� */
-int g_packet_io_thread_num = 1;
-int g_app_send_rst_type;
-extern int g_packet_io_ipv6_switch;
-int g_packet_io_ipv6_raw_socket = 0; /* ���ڷ��ʹ�Ipv6 rst�� */
-extern int g_timestamp_record_sw;
-int g_encapsulate_with_ddp = 0; /* ʹ��DDPЭ���װ��ԭʼ�� */
-int g_encapsulate_with_L2E = 0; /* ʹ��DDPЭ���װ��x27ԭʼIP�� */
- /*
- 2015-12-10 lijia add, ����eth��, ���账��MAC��ַ, ���贴����ʱCOPY�����ṹ�� ,
- ԭʼ����IP�㿪ʼ.
- */
-int g_skip_ethernet_layer_sw = 0;
-void *g_packet_dl_send_handle[MAX_THREAD_NUM];/* ��̬IO��ķ������ */
-//static int g_packet_io_dir; /* ���ڼ�¼��ǰ��������, �����ʱʹ�� */
-int G_SKIP_NOT_IP_LAYER = 0; /* ������IPЭ��IJ�, ����˫ջ�������⻷����, RST������ */
-static int mesa_default_pkt_cb(const raw_pkt_t *p_raw_pkt, unsigned char dir, int thread_num);
-PACKET_IO_CB_T G_DEFAULT_PKT_CB = mesa_default_pkt_cb;
-
-dl_io_fun_list_t dl_io_fun_list;
-static int use_custom_pkt_cb = 0; /* �Ƿ������µ�callback���� */
-long long g_timedelay_threshold = 10000000; /* ��λCPU������, ��ʱ�� */
-
-int g_use_MESA_sleep_sw = 0;
-int g_raw_pkt_broken_check = 0; /* ���ԭʼ���Ƿ��޸� */
-static UINT8 *g_send_buf_pool[MAX_THREAD_NUM];
-
-#define MAX_RAW_PKT_TARGET_NUM (128)
-
-typedef struct{
- unsigned int target_id; /* Ŀ��ID */
- send_raw_args_t send_args[__CAP_MODEL_MAX];
-}send_raw_pkt_info_t;
-
-static send_raw_pkt_info_t G_SND_RAW_PKT_INFO[MAX_RAW_PKT_TARGET_NUM];
-static int G_SND_RAW_PKT_INFO_NUM = 0;
-
-void packet_io_exit(void);
-int packet_io_lib_load(int cap_mode);
-void del_last_rn(char *data, int max_len);
-static int parse_send_raw_pkt_conf(void);
-int parse_send_route_conf(const char *profile_path);
-int parse_send_gdev_ip_conf(const char *profile_path);
-extern void cycle_pkt_dump(int thread_seq, const raw_pkt_t *p_raw_pkt);
-extern char *MESA_MD5_sum_bin(unsigned char *raw_data, unsigned int raw_data_len, char result[16]);
-extern void timestamp_region_update(int tid, long long cpu_cycle);
-void pptp_exit(void);
-extern void ipv4_frag_per_thread_exit(int thread_seq);
-extern void ipv6_frag_per_thread_exit(int thread_seq);
-extern void pptp_per_thread_exit(int thread_seq);
-extern void __timestamp_print_max_tuple4(const raw_pkt_t *raw_pkt, long timedelay, int tid);
-
-static const unsigned char phony_feedback_eth_hdr_ip4[ETHERNET_HDR_LEN] =
- {0x50, 0x48, 0x4F, 0x4E, 0x59, 0x5F, 0x4D, 0x41, 0x43, 0x41, 0x44, 0x44, 0x08, 0x00}; /* PHONY_MACADD + ipv4 */
-static const unsigned char phony_feedback_eth_hdr_ip6[ETHERNET_HDR_LEN] =
- {0x50, 0x48, 0x4F, 0x4E, 0x59, 0x5F, 0x4D, 0x41, 0x43, 0x41, 0x44, 0x44, 0x86, 0xDD}; /* PHONY_MACADD + ipv6*/
-
-int packet_io_set_ipv6_module_enable(int op_switch)
-{
- g_packet_io_ipv6_switch = op_switch;
- return 0;
-}
-
-int packet_io_set_ipv6_raw_socket_enable(int op_switch)
-{
- g_packet_io_ipv6_raw_socket = op_switch;
- return 0;
-}
-
-int packet_io_register_cb(PACKET_IO_CB_T fun)
-{
- int ret = 0;
-
- use_custom_pkt_cb = 1;
- if(dl_io_fun_list.dl_io_register_cb){
- ret = dl_io_fun_list.dl_io_register_cb(fun);
- }else{
- printf("Warning, packet io library not support 'dl_io_register_cb'!\n");
- }
-
- return ret;
-}
-
-int packet_io_set_cap_level(int cap_level)
-{
- int ret = 0;
- g_packet_io_cap_level = cap_level;
-
- if(dl_io_fun_list.dl_io_set_cap_level){
- ret = dl_io_fun_list.dl_io_set_cap_level(cap_level);
- }else{
- printf("Warning, packet io library not support 'dl_io_set_cap_level'!\n");
- }
-
- return ret;
-}
-
-int packet_io_set_work_thread_num(int thread_num)
-{
- int ret = 0;
-
- if(dl_io_fun_list.dl_io_set_work_thread_num){
- ret = dl_io_fun_list.dl_io_set_work_thread_num(thread_num);
- }else{
- printf("Warning, packet io library not support 'dl_io_set_work_thread_num'!\n");
- }
-
- g_packet_io_thread_num = thread_num;
-
- return ret;
-}
-
-int packet_io_set_cap_mode(int cap_mode)
-{
- int ret = 0;
-
- if(dl_io_fun_list.dl_io_set_cap_mode){
- ret = dl_io_fun_list.dl_io_set_cap_mode(cap_mode);
- }else{
- printf("Warning, packet io library not support 'dl_io_set_cap_mode'!\n");
- }
-
- return ret;
-}
-
-/*
- Ϊ�˷����û����ã������ļ��е�ֵ�Ƚϼ򵥣���0��1��2��3�ȣ�
- �ڴ��е�ֵ����Ƚϸ��ӣ���Ҫ�˺���ת��һ��.
-*/
-static int topology_mode_convert(int config_value)
-{
- int private_value;
-
- switch(config_value)
- {
- case 0:
- private_value = NET_CONN_PARA_NOSEND;
- break;
-
- case 1:
- private_value = NET_CONN_PARALLEL;
- break;
-
- case 2:
- private_value = NET_CONN_SERIAL_2CARD;
- break;
-
- case 3:
- private_value = NET_CONN_SERIAL_GDEV;
- break;
-
- default:
- private_value = -1;
- break;
- }
-
- return private_value;
-}
-
-int packet_io_set_topology_mode(int user_topology_mode)
-{
- int private_top_mode, ret = -1;
-
- private_top_mode = topology_mode_convert(user_topology_mode);
- if(private_top_mode < 0){
- return -1;
- }
-
- g_topology_mode = private_top_mode;
-
- if(dl_io_fun_list.dl_io_set_topology_mode){
- ret = dl_io_fun_list.dl_io_set_topology_mode(private_top_mode);
- }else{
- printf("Warning, packet io library not support 'dl_io_set_topology_mode'!\n");
- }
-
- return ret;
-}
-
-int packet_io_set_capdev_parallel(const char *cap_dev)
-{
- int ret = 0;
-
- if(dl_io_fun_list.dl_io_set_capdev_parallel){
- ret = dl_io_fun_list.dl_io_set_capdev_parallel(cap_dev);
- }else{
- printf("Warning, packet io library not support 'dl_io_set_capdev_parallel'!\n");
- }
-
- strncpy(g_up_dev_name, cap_dev, DEV_NAME_STR_LEN);
-
- return ret;
-}
-
-int packet_io_set_capdev_serial(const char *up_dev, const char *down_dev)
-{
- int ret = 0;
-
- if(dl_io_fun_list.dl_io_set_capdev_serial){
- ret = dl_io_fun_list.dl_io_set_capdev_serial(up_dev, down_dev);
- }else{
- printf("Warning, packet io library not support 'dl_io_set_capdev_serial'!\n");
- }
-
- strncpy(g_up_dev_name, up_dev, DEV_NAME_STR_LEN);
- strncpy(g_down_dev_name, down_dev, DEV_NAME_STR_LEN);
-
- return ret;
-}
-
-int packet_io_set_send_dev(const char *send_dev)
-{
- int ret;
-
- ret = snprintf(g_send_dev_name, DEV_NAME_STR_LEN, "%s", send_dev);
- if(ret >= DEV_NAME_STR_LEN){
- printf("send device name is too long!\n");
- return -1;
- }
-
- return ret;
-}
-
-int packet_io_set_gateway_mac(const char *gateway_mac)
-{
- if(MESA_mac_pton(gateway_mac, ':', (char *)g_send_gateway_mac) < 0){
- printf("error, gateway mac:%s is not correct, for example:00:11:22:33:44:55\n", gateway_mac);
- return -1;
- }
-
- return 0;
-}
-
-int packet_io_set_capture_filter(const char *filter_rule)
-{
- int ret = 0;
-
- if(dl_io_fun_list.dl_io_set_capture_filter){
- ret = dl_io_fun_list.dl_io_set_capture_filter(filter_rule);
- }else{
- printf("Warning, packet io library not support 'dl_io_set_capture_filter'!\n");
- }
-
- return ret;
-}
-
-
-long packet_io_get_app_drop_num(int thread_num)
-{
- long ret = 0;
-
- if(dl_io_fun_list.dl_io_get_app_drop_num){
- ret = dl_io_fun_list.dl_io_get_app_drop_num(thread_num);
- }else{
- printf("Warning, packet io library not support 'dl_io_get_app_drop_num'!\n");
- }
-
- return ret;
-}
-
-
-long packet_io_get_app_drop_num_tot(void)
-{
- int i;
- long ret = 0;
-
- for(i = 0; i < g_packet_io_thread_num; i++){
- ret += packet_io_get_app_drop_num(i);
- }
-
- return 0;
-}
-
-long packet_io_get_lib_drop_num(void)
-{
- long ret = 0;
-
- if(dl_io_fun_list.dl_io_get_lib_drop_num){
- ret = dl_io_fun_list.dl_io_get_lib_drop_num();
- }else{
- printf("Warning, packet io library not support 'dl_io_get_lib_drop_num'!\n");
- }
-
- return ret;
-}
-
-int packet_io_set_cap_buf_queue(int queue_num_max)
-{
- int ret = 0;
-
- if(dl_io_fun_list.dl_io_set_cap_buf_queue){
- ret = dl_io_fun_list.dl_io_set_cap_buf_queue(queue_num_max);
- }else{
- printf("Warning, packet io library not support 'dl_io_set_cap_buf_queue'!\n");
- }
-
- return ret;
-}
-
-static int packet_io_process_ddp_pkt(const MESA_feedback_raw_pkt_t *ddp_fix_hdr,
- int ddp_payload_len, raw_pkt_t *p_raw_pkt, unsigned char dir, int thread_num)
-{
- const char *ddp_payload;
- //int pkt_index = 1; //�����ݲ�֧��DDP�ۺ�ԭʼ��
- if(MESA_FEEDBACK_HDR_MAGIC != ddp_fix_hdr->property_hdr.magic){
- return PASS;
- }
-
- if(0 != ddp_fix_hdr->property_hdr.stream){
- return PASS;
- }
-
- if((MESA_FEEDBACK_DTYPE_IPv4 != ddp_fix_hdr->property_hdr.data_type)
- && (MESA_FEEDBACK_DTYPE_IPv6 != ddp_fix_hdr->property_hdr.data_type)){
- return PASS;
- }
-
- ddp_payload = (const char *)((char *)ddp_fix_hdr + sizeof(MESA_feedback_raw_pkt_t));
-
-#if 0 /* �������Զ����0, ͨ��IPͷ��ȡ�İ�������ʵ�ʲ���, ����Ҳ��֧��VLAN, PPPOE�����ݰ�, �����ݲ�֧��DDP�ۺ�ԭʼ��, һ��DDP��ֻȡһ��ԭʼ�� */
- while(ddp_payload_len > 0)
- {
- p_raw_pkt->raw_pkt_len = get_pkt_len_from_eth_hdr((const struct mesa_ethernet_hdr *)ddp_payload);
- if(p_raw_pkt->raw_pkt_len < 0){
- sapp_runtime_log(30, "ddp raw pkt parse error, pkt index:%d\n", pkt_index);
- break;
- }
-#else
- {
- p_raw_pkt->raw_pkt_len = ddp_payload_len;
-#endif
- p_raw_pkt->raw_pkt_data = (char *)ddp_payload;
-#if CYCLE_PKT_DUMP
- /* 2017-10-09 lijia add, for tcpdump_mesa capture ddp inner packet */
- cycle_pkt_dump(thread_num, p_raw_pkt);
-#endif
- eth_entry(NULL, p_raw_pkt->raw_pkt_data, thread_num, dir, p_raw_pkt, 0);
-
-#if 0
- ddp_payload += p_raw_pkt->raw_pkt_len;
- ddp_payload_len -= p_raw_pkt->raw_pkt_len;
- if(ddp_payload_len < 0){
- sapp_runtime_log(30, "ddp raw pkt parse error, pkt index:%d\n", pkt_index);
- break;
- }
- pkt_index++;
-#endif
- }
-
- return PASS;
-}
-
-static int packet_io_strip_ddp_hdr(const raw_pkt_t *p_raw_pkt, unsigned char dir, int thread_num)
-{
- int ret;
- const MESA_feedback_raw_pkt_t *ddp_raw_pkt_hdr = NULL;
- int ddp_payload_len = p_raw_pkt->raw_pkt_len; /* DDP���ݳ���, ���������ڲ����ddpͷ���͸��� */
-
- switch(p_raw_pkt->low_layer_type){
- case CAP_LEVEL_MAC:
- {
- const struct mesa_ethernet_hdr *ethh = (const struct mesa_ethernet_hdr *)p_raw_pkt->raw_pkt_data;
- if(ETHERTYPE_IP == ntohs(ethh->ether_type)){
- const struct mesa_ip4_hdr *ip4h = (const struct mesa_ip4_hdr *)((char *)ethh + sizeof(struct mesa_ethernet_hdr));
- ddp_raw_pkt_hdr = (const MESA_feedback_raw_pkt_t *)((char *)ip4h + ip4h->ip_hl * 4 + sizeof(struct mesa_udp_hdr));
- ddp_payload_len -= sizeof(struct mesa_ethernet_hdr) + sizeof(struct mesa_ip4_hdr) + sizeof(struct mesa_udp_hdr) + sizeof(MESA_feedback_raw_pkt_t);
- }else{
- /* �ݲ�֧��������ʽ��DDPԭʼ���ش� */
- sapp_runtime_log(30, "ddp raw pkt parse error, unknown ether_type:0x%x\n", ntohs(ethh->ether_type));
- return PASS;
- }
- }
- break;
-
- case CAP_LEVEL_IPV4:
- {
- const struct mesa_ip4_hdr *ip4h = (const struct mesa_ip4_hdr *)p_raw_pkt->raw_pkt_data;
- ddp_raw_pkt_hdr = (const MESA_feedback_raw_pkt_t *)((char *)ip4h + ip4h->ip_hl * 4 + sizeof(struct mesa_udp_hdr));
- ddp_payload_len -= sizeof(struct mesa_ip4_hdr) + sizeof(struct mesa_udp_hdr) + sizeof(MESA_feedback_raw_pkt_t);
- }
- break;
-
- default:
- return PASS;
- break;
- }
-
- ret = packet_io_process_ddp_pkt(ddp_raw_pkt_hdr, ddp_payload_len, (raw_pkt_t *)p_raw_pkt, dir, thread_num);
-
- return ret;
-}
-
-
-#if 1 /* for xx7 �ӿ� */
-
-typedef struct {
- uint32_t magic_num;
- uint8_t version;
- uint8_t msg_type;
- uint16_t flag;
- uint32_t cont_len; /* ������ͷ����12�ֽ�! */
-}L2E_msg_header_t; /*sizeof = 12B */
-
-
-
-typedef struct {
- uint16_t data_len; /* ������ͷ����4�ֽ� */
- uint16_t data_type;
- uint8_t data_value[0];
-}L2E_data_small_block_hdr_t;
-
-struct __msg_small_body_t{
- uint32_t cap_ip; // ǰ�˽ڵ�IP
- uint32_t data_id; // �����н����Ψһ���
- uint16_t unit_num; //С���ݿ�ĸ���
- L2E_data_small_block_hdr_t small_unit[0]; //С���ݿ�����
-}__attribute__((packed));
-typedef struct __msg_small_body_t L2E_msg_small_body_hdr_t;
-
-
-#endif
-
-/*
- 3x7��Ŀ�ش���ԭʼ��ͷ��.
-*/
-static int packet_io_strip_L2E_hdr(raw_pkt_t *p_raw_pkt, unsigned char dir, int thread_num)
-{
- int ret;
-#define L2E_HDR_TOTAL_LEN (78)
-#define L2E_PKT_HDR_MAGIC 0xD0BADABA
- const struct mesa_ethernet_hdr *ethh = (const struct mesa_ethernet_hdr *)p_raw_pkt->raw_pkt_data;
- const unsigned int *l2e_hdr_magic;
- unsigned char *L2E_payload;
- int L2E_len;
- const L2E_msg_header_t *L2E_msg_hdr;
- const L2E_data_small_block_hdr_t *small_block_hdr;
- const L2E_msg_small_body_hdr_t *small_block_body;
- int i;
-
- /* һЩ������ */
- if(ntohs(ethh->ether_type) != ETHERTYPE_IP){
- return PASS;
- }
-
- const struct mesa_ip4_hdr *ip4h = (const struct mesa_ip4_hdr *)((char *)p_raw_pkt->raw_pkt_data + sizeof(struct mesa_ethernet_hdr));
- if(ip4h->ip_p != IPPROTO_UDP){
- return PASS;
- }
-
- if(ntohs(ip4h->ip_len) < sizeof(struct mesa_ip4_hdr)/* �����ipͷ */ + sizeof(struct mesa_udp_hdr)/* ���udpͷ */ + L2E_HDR_TOTAL_LEN + sizeof(struct mesa_ip4_hdr)/* �ڲ�IP��ͷ */){
- return PASS;
- }
-
- L2E_payload = (unsigned char *)p_raw_pkt->raw_pkt_data + sizeof(struct mesa_ethernet_hdr) + sizeof(struct mesa_ip4_hdr) + sizeof(struct mesa_udp_hdr);
- L2E_len = p_raw_pkt->raw_pkt_len - sizeof(struct mesa_ethernet_hdr) - sizeof(struct mesa_ip4_hdr) - sizeof(struct mesa_udp_hdr);
-
- while(L2E_len > 0){
- L2E_msg_hdr = (L2E_msg_header_t *)L2E_payload;
- if(L2E_msg_hdr->magic_num != L2E_PKT_HDR_MAGIC){
- sapp_runtime_log(20, "L2E hdr error, magic is:%x\n", L2E_msg_hdr->magic_num);
- return PASS;
- }
-
- L2E_payload += sizeof(L2E_msg_header_t);
- L2E_len -= sizeof(L2E_msg_header_t);
-
- if(L2E_len < (int)L2E_msg_hdr->cont_len ){
- sapp_runtime_log(20, "L2E hdr error, left payload len is %d, smaller than hdr declare len:%d!\n", L2E_len, L2E_msg_hdr->cont_len);
- return PASS;
- }
-
- if(L2E_msg_hdr->msg_type != 2){ /* 1:meta data; 2:small block; 3:big block, ֻ����С�������е�IP��, ��������������! */
- L2E_payload += L2E_msg_hdr->cont_len;
- L2E_len -= L2E_msg_hdr->cont_len;
- continue;
- }
-
- small_block_body = (L2E_msg_small_body_hdr_t *)L2E_payload;
- L2E_payload += sizeof(L2E_msg_small_body_hdr_t);
- L2E_len -= sizeof(L2E_msg_small_body_hdr_t);
-
- for(i = 0; i < small_block_body->unit_num; i++){
- small_block_hdr = (L2E_data_small_block_hdr_t *)L2E_payload;
- if(small_block_hdr->data_type != 0x0002){ /* 0x0002: ԭʼIP�� */
- L2E_payload += small_block_hdr->data_len;
- L2E_len -= small_block_hdr->data_len;
- continue;
- }
-
- /* ����raw_pktָ�� */
- p_raw_pkt->raw_pkt_data = L2E_payload + sizeof(L2E_data_small_block_hdr_t);
- p_raw_pkt->raw_pkt_len = small_block_hdr->data_len - sizeof(L2E_data_small_block_hdr_t);
- p_raw_pkt->low_layer_type = ADDR_TYPE_IPV4;
-#if CYCLE_PKT_DUMP
- /* for tcpdump_mesa capture ddp inner packet */
- cycle_pkt_dump(thread_num, p_raw_pkt);
-#endif
- ret = ipv4_entry(NULL, p_raw_pkt->raw_pkt_data, thread_num, dir, p_raw_pkt, 0);
-
- L2E_payload += small_block_hdr->data_len;
- L2E_len -= small_block_hdr->data_len;
- }
- }
-
- return ret;
-}
-
-static int mesa_default_pkt_cb(const raw_pkt_t *p_raw_pkt, unsigned char dir, int thread_num)
-{
- int ret = PASS;
- long long before_call = 0, after_call, timecost;
-
- before_call = sapp_get_cpu_cycle();
-
-#if DEBUG
- char raw_pkt_md5_before[16];
- char raw_pkt_md5_after[16];
-
- if(unlikely(g_raw_pkt_broken_check != 0)){
- MESA_MD5_sum_bin((unsigned char *)p_raw_pkt->raw_pkt_data, p_raw_pkt->raw_pkt_len, raw_pkt_md5_before);
- }
-#endif
-
- if(unlikely(g_encapsulate_with_ddp)){
- /* ����ddp���װ���ܺ�, ��packet_io_process_ddp_pkt()�����в���DDP�������� */
- ret = packet_io_strip_ddp_hdr(p_raw_pkt, dir, thread_num);
- } else if(unlikely(g_encapsulate_with_L2E)){
- ret = packet_io_strip_L2E_hdr((raw_pkt_t *)p_raw_pkt, dir, thread_num);
- }else{
-
-#if CYCLE_PKT_DUMP
- cycle_pkt_dump(thread_num, p_raw_pkt);
-#endif
- switch(p_raw_pkt->low_layer_type){
- case CAP_LEVEL_MAC:
- ret = eth_entry(NULL,p_raw_pkt->raw_pkt_data,thread_num,dir, p_raw_pkt, 0);
- break;
-
- case CAP_LEVEL_IPV4:
- ret = ipv4_entry(NULL,(void *)p_raw_pkt->raw_pkt_data,thread_num,dir, p_raw_pkt, 0);
- break;
-
- case CAP_LEVEL_IPV6:
- ret = ipv6_entry(NULL,(void *)p_raw_pkt->raw_pkt_data,thread_num,dir, p_raw_pkt, 0);
- break;
-
- default:
- return PASS;
- break;
- }
- }
-
- after_call = sapp_get_cpu_cycle();
- timecost = after_call - before_call;
- timestamp_region_update(thread_num, timecost);
-
-#if DEBUG
- if(unlikely(g_timestamp_record_sw)){
- if(timecost > g_timedelay_threshold){
- __timestamp_print_max_tuple4(p_raw_pkt, timecost, thread_num);
- }
- }
-
- if(unlikely(g_raw_pkt_broken_check != 0)){
- MESA_MD5_sum_bin((unsigned char *)p_raw_pkt->raw_pkt_data, p_raw_pkt->raw_pkt_len, raw_pkt_md5_after);
-
- if(memcmp(raw_pkt_md5_before, raw_pkt_md5_after, 16) != 0){
- printf("\033[41mraw packet is broken involuntarily! If you don't care, please disable 'raw_pkt_broken_check' in main.conf!\033[0m\n");
- abort();
- }
- }
-#endif
-
- return ret;
-}
-
-
-void packet_io_exit(void)
-{
- /* ����ģʽ��, �������߳�һЩʱ��, ����δ�������, ����MESA_tcp�첽�������ݵȵ�. */
- sched_yield();
- sleep(1);
- sched_yield();
- sleep(1);
-
- exit(1);
-
- return;
-}
-
-int packet_io_init(int argc, char *argv[])
-{
- int i;
-
- if(0 == use_custom_pkt_cb){
- packet_io_register_cb(mesa_default_pkt_cb);
- }
-
- if(NULL == dl_io_fun_list.dl_io_init){
- printf("Error, packet io library must support 'dl_io_init' !\n");
- exit(0);
- }
-
- if(dl_io_fun_list.dl_io_init(argc, argv) < 0){
- return -1;
- }
-
- for(i = 0; i < MAX_THREAD_NUM; i++){
- g_send_buf_pool[i] = (UINT8 *)malloc(SENDPACKET_BUF_LEN);
- }
-
- if(sendpacket_init_new(g_packet_io_thread_num) < 0){
- printf("Error, sendpacket_init_new error !\n");
- return -1;
- }
-
-#if 0 /* 20161117 lijia move to send_handle_init() */
- for(i = 0; i < g_packet_io_thread_num; i++){
- g_packet_dl_send_handle[i] = dl_io_fun_list.dl_io_get_send_handle(i);
- }
-#endif
-
- if(CAP_MODEL_PCAP_DUMPFILE == g_packet_io_cap_mode){
- dl_io_fun_list.dl_io_register_exit_cb(packet_io_exit);
- }
-
- if(g_send_dev_name[0] != '\0'){
- if(MESA_get_dev_mac(g_send_dev_name, g_send_dev_mac) < 0){
- printf("Warning, can't get %s mac addr!\n", g_send_dev_name);
- }
- }else{
- printf("Warning, not assign send device!\n");
- }
-
- gdev_init();
-
- parse_send_gdev_ip_conf("conf/send_gdev.conf");
-
- parse_send_route_conf("conf/send_route.conf");
-
- parse_send_raw_pkt_conf();
-
- packet_io_status_init();
-
- return 0;
-}
-
-extern int g_StreamTcpAllFunNum;
-extern int g_Ipv6FunNum;
-extern int app_function_rationality_check(void);
- /* not return until error, or use 'CAP_MODEL_PCAP_DUMPFILE' mode */
-void packet_io_run(void)
-{
- pthread_t pid;
- if(NULL == dl_io_fun_list.dl_io_run){
- printf("Error, packet io library must support 'dl_io_run' !\n");
- sapp_runtime_log(RLOG_LV_FATAL, "%s:%d: Error, packet io library must support 'dl_io_run' !\n", __FILE__, __LINE__);
- assert(0);
- }
-
- app_function_rationality_check();
-
- pthread_create(&pid, NULL, time_event_thread ,NULL);
-
- dl_io_fun_list.dl_io_run();
-
- while(1){
- pause();
- }
-}
-
-extern volatile int update_packet_io_status_sw;
-void packet_io_clean_thread_context(int thread_seq)
-{
- if(1 == update_packet_io_status_sw){
- sysinfo_output(); /* ���һ��дͳ����Ϣ, �رձ�־λ, ��Ϊ�����������, ��д��û������ */
- update_packet_io_status_sw = 0;
- }
-
- free_thread_stream(thread_seq);
-
- ipv4_frag_per_thread_exit(thread_seq);
- ipv6_frag_per_thread_exit(thread_seq);
- pptp_per_thread_exit(thread_seq);
-}
-
-
-MESA_send_handle *packet_io_get_send_handle(int thread_id)
-{
- return &g_send_handle[thread_id];
-}
-
-
-unsigned char *packet_io_get_sendbuf(int type, int thread_num)
-{
- if(g_topology_mode & __NET_CONN_PARALLEL){
- return g_send_buf_pool[thread_num];
- }
-
- return dl_io_fun_list.dl_io_get_sendbuf(g_packet_dl_send_handle[thread_num], thread_num);
-}
-
-void packet_io_free_sendbuf(int type, int thread_num)
-{
- if(g_topology_mode & __NET_CONN_PARALLEL){
- return; /* use static global variable, do nothing */
- }
-
- dl_io_fun_list.dl_io_free_sendbuf(g_packet_dl_send_handle[thread_num], thread_num);
- return;
-}
-
-
-static int packet_io_calc_ethernet_offset_to_ip(const unsigned char *sendbuf)
-{
- int offset;
- const struct mesa_ethernet_hdr *outer_ehdr;
- ///const struct mesa_ethernet_hdr *inner_ehdr;
-
- if(sapp_global_single.send_fake_pkt_mode == SEND_PKT_MODE_GDEV){
- sendbuf += VXLAN_HDR_RESERVED_LEN; /* vxlanģʽ��Ԥ����vxlan�����mac,ip,udpͷ��, ��ת���ڲ�macͷ */
- }
-
- switch(g_packet_io_cap_level){
- case CAP_LEVEL_IPV4:
- offset = 0;
- break;
-
- case CAP_LEVEL_MAC:
- outer_ehdr = (struct mesa_ethernet_hdr *)sendbuf;
- if(ETHERTYPE_PANGU_MAC_IN_MAC == ntohs(outer_ehdr->ether_type)){
- offset = MAC_IN_MAC_HDR_LEN;
- }else{
- offset = sizeof(struct mesa_ethernet_hdr);
- }
- break;
-
- default:
- offset = -1;
- sapp_runtime_log(RLOG_LV_FATAL, "MESA_kill_tcp: Invalid cap_mode:%d\n", g_packet_io_cap_level);
- return -1;
- }
-
- return offset;
-}
-
-static int packet_io_send_by_sys_routev4(MESA_send_handle *send_handle,int datalen,int dir,
- char *feedback_buf, int *feedback_buf_len)
-{
- int ret, offset = 0;
- struct sockaddr_in sock_addr_v4;
- char *actual_data_ptr;
- struct mesa_ip4_hdr *ip4_hdr;
-
- offset = packet_io_calc_ethernet_offset_to_ip(send_handle->send_buf);
- if(offset < 0){
- return -1;
- }
-
- /* ʹ��ϵͳ·��ʱ, MAC��ַ��Э��ջ���, ָ��ͳ���Ҫ��ȥETHͷ�� */
-#if 0
- actual_data_ptr = (char *)send_handle->send_buf + sizeof(mesa_ethernet_hdr);
- datalen -= sizeof(mesa_ethernet_hdr);
-#else
- actual_data_ptr = (char *)send_handle->send_buf + offset;
- datalen -= offset;
-
-#endif
-
- ip4_hdr = (struct mesa_ip4_hdr *)actual_data_ptr;
-
- memset(&sock_addr_v4, 0, sizeof(struct sockaddr_in));
- sock_addr_v4.sin_family = AF_INET;
- /* build_ipv4ʱ�Ѿ���dir������õ�ַ, �˴�ֱ��ʹ��ip_dst���� */
- sock_addr_v4.sin_addr.s_addr = ip4_hdr->ip_dst.s_addr;
-
- //if(sapp_global_single.send_fake_pkt_mode != 0){
- // return packet_io_send_fake_pkt_by_gdev(send_handle, ADDR_TYPE_IPV4,
- // actual_data_ptr+VXLAN_HDR_RESERVED_LEN, datalen, dir,
- // feedback_buf, feedback_buf_len);
- //}
-
-retry:
- ret = sendto(send_handle->raw_ipv4_fd, actual_data_ptr, datalen, 0,
- (struct sockaddr *)&sock_addr_v4, sizeof(struct sockaddr));
- if(ret < 0){
- if(EINTR == errno){
- goto retry; /* ���ź��жϵ�IO������Ҫ���� */
- }else{
- g_SysInputInfo[send_handle->threadnum][SEND_PKT_ERR]++;
- g_SysInputInfo[send_handle->threadnum][SEND_PKT_ERR_LEN] += datalen;
- sapp_runtime_log(RLOG_LV_FATAL, "%s:%d: sendto error, %s\n", __FILE__,__LINE__,strerror(errno));
- return ret;
- }
- }
-
- /* �Ƿ���Ҫ��Inject�������������� */
- if(feedback_buf != KILL_TCP_PHONY_POINTER){
- if(*feedback_buf_len < ret + (int)sizeof(struct mesa_ethernet_hdr)){
- return -2;
- }
-
- memcpy(feedback_buf, phony_feedback_eth_hdr_ip4, ETHERNET_HDR_LEN);
-
- memcpy(feedback_buf + sizeof(struct mesa_ethernet_hdr), actual_data_ptr, datalen);
-
- *feedback_buf_len = datalen + sizeof(struct mesa_ethernet_hdr);
- }
-
- return ret;
-}
-
-static int packet_io_send_by_sys_routev6(MESA_send_handle *send_handle,int datalen,int dir,
- char *feedback_buf, int *feedback_buf_len)
-{
- int ret;
- struct sockaddr_in6 sock_addr_v6;
- char *actual_data_ptr;
- struct mesa_ip6_hdr *ip6_hdr;
- int offset;
-
- if(0 == g_packet_io_ipv6_raw_socket){
- printf("IPv6 module is not support! Please check 'main.conf->IPv6_raw_socket'.\n");
- sapp_runtime_log(RLOG_LV_FATAL, "%s:%d: IPv6 module is not support! Please check 'main.conf->IPv6_raw_socket'.\n", __FILE__, __LINE__);
- return -1;
- }
-
- offset = packet_io_calc_ethernet_offset_to_ip(send_handle->send_buf);
- if(offset < 0){
- return -1;
- }
-
- /* ʹ��ϵͳ·��ʱ, MAC��ַ��Э��ջ���, ָ��ͳ���Ҫ��ȥETHͷ�� */
-#if 0
- actual_data_ptr = (char *)send_handle->send_buf + sizeof(struct mesa_ethernet_hdr);
- datalen -= sizeof(struct mesa_ethernet_hdr);
-#else
- /* 2018-09-13 lijia modify, adjust MAC_IN_MAC header */
- actual_data_ptr = (char *)send_handle->send_buf + offset;
- datalen -= offset;
-#endif
-
- ip6_hdr = (struct mesa_ip6_hdr *)actual_data_ptr;
-
- memset(&sock_addr_v6, 0, sizeof(struct sockaddr_in6));
- sock_addr_v6.sin6_family = AF_INET6;
- memcpy(sock_addr_v6.sin6_addr.s6_addr, ip6_hdr->ip6_dst.s6_addr, IPV6_ADDR_LEN);
-
-retry:
- ret = sendto(send_handle->raw_ipv6_fd, actual_data_ptr, datalen, 0,
- (struct sockaddr *)&sock_addr_v6, sizeof(struct sockaddr_in6));
- if(ret < 0){
- if(EINTR == errno){
- goto retry; /* ���ź��жϵ�IO������Ҫ���� */
- }else{
- g_SysInputInfo[send_handle->threadnum][SEND_PKT_ERR]++;
- g_SysInputInfo[send_handle->threadnum][SEND_PKT_ERR_LEN] += datalen;
- sapp_runtime_log(RLOG_LV_FATAL,"%s:%d: packet_io_send_by_sys_routev6() sendto error, %s\n", __FILE__,__LINE__,strerror(errno));
- return ret;
- }
- }
-
- if(feedback_buf != KILL_TCP_PHONY_POINTER){
- if(*feedback_buf_len < ret + (int)sizeof(struct mesa_ethernet_hdr)){
- return -2;
- }
-
- memcpy(feedback_buf, phony_feedback_eth_hdr_ip6, ETHERNET_HDR_LEN);
-
- memcpy(feedback_buf + sizeof(struct mesa_ethernet_hdr), actual_data_ptr, datalen);
- *feedback_buf_len = datalen + sizeof(struct mesa_ethernet_hdr);
- }
-
- return ret;
-}
-
-static int packet_io_get_sendroute_mac(char dev_id, char link_id, unsigned char *out_mac_addr)
-{
- char *p_mac_addr = (char *)g_send_gateway_mac_table[dev_id][link_id];
- if(G_SND_ROUTE_INFO_NUM <= 0 || strlen(p_mac_addr) <= 0)return -1;
- else
- {
- if(MESA_mac_pton(p_mac_addr, ':', (char *)out_mac_addr) < 0){
- printf("error, src mac:%s is not correct, for example:00:11:22:33:44:55\n", p_mac_addr);
- return -1;
- }
- }
- return 0;
-}
-
-static int packet_io_send_by_manual_conf(MESA_send_handle *send_handle,int datalen,
- int dir, UINT16 ether_type)
-{
- int ret;
-
- /* to do:
- ��ȡ����ip, mac ��Ϣ,
- �����ֹ�����,
- ����ݷ���/proc/net/route, /proc/net/arp�Զ���ȡ!
-
- get_gateway_info_by_manual();
- get_gateway_info_aotu();
-
- */
-
-#if 0 /* for test, use 10.0.6.201 mac addr */
- static char mac_201_gateway[6] = {0xdc, 0xd2, 0xfc, 0x66, 0xec, 0xb2};
- static char mac_201_em2[6] = {0x74, 0x86,0x7A,0xD0,0x12,0xFD};
-
- memcpy(g_send_gateway_mac, mac_201_gateway, 6);
- memcpy(g_send_dev_mac, mac_201_em2, 6);
-
-#endif
- const struct streaminfo_private *pstrem_pr = (const struct streaminfo_private *)send_handle->user_arg;
- const struct streaminfo *pstream = (const struct streaminfo *)send_handle->user_arg;
- const struct streaminfo *tmpstream = pstream;
- struct vxlan_info mim_mem_hdr;
- int opt_len = sizeof(mim_mem_hdr);
- ret = MESA_get_stream_opt(tmpstream, MSO_STREAM_VXLAN_INFO, &mim_mem_hdr, &opt_len);
- if(ret < 0){
- sapp_runtime_log(20, "packet_io_send_by_manual_conf(): get vxlan info error!\n");
- return -1;
- }
- unsigned char send_route_mac[MAC_ADDR_LEN] = "";
- unsigned char *p_dst_mac;
-
- if(sapp_global_single.send_fake_pkt_mode == SEND_PKT_MODE_STACK_2_LAYER_MUTI_ROUTE )
- {
- ret = packet_io_get_sendroute_mac(mim_mem_hdr.dev_id, mim_mem_hdr.link_id, send_route_mac);
- if(ret < 0){
- sapp_runtime_log(20, "packet_io_send_by_manual_conf(): get sendroute_mac info using %d:%d error!\n", mim_mem_hdr.dev_id, mim_mem_hdr.link_id);
- return -1;
- }
- p_dst_mac = send_route_mac;
- }
- else
- {
- p_dst_mac = g_send_gateway_mac;
- }
- sendpacket_build_ethernet(p_dst_mac, g_send_dev_mac, ether_type, NULL, 0, send_handle->send_buf);
-
-send_again:
- ret = sendto(send_handle->raw_eth_fd, send_handle->send_buf, datalen, 0,
- (struct sockaddr *)&send_handle->saddr_raw_eth, sizeof(struct sockaddr));
- if(ret < 0){
- if((EAGAIN == errno) || (EINTR == errno) ){
- goto send_again;
- }else{
- return -1;
- }
- }
-
- return ret;
-}
-
-int packet_io_send_fake_pkt(MESA_send_handle *send_handle,int datalen,int send_type,
- int low_layer_type, int dir,int thread_num,
- char *feedback_buf, int *feedback_buf_len)
-{
- int ret;
- UINT16 ether_type;
-
- if(g_topology_mode & __NET_CONN_PARALLEL)
- {
- if(sapp_global_single.send_fake_pkt_mode == SEND_PKT_MODE_GDEV)
- {
- ret = packet_io_send_fake_pkt_by_gdev(send_handle, (enum addr_type_t)low_layer_type,
- (char *)send_handle->send_buf, datalen, dir, feedback_buf, feedback_buf_len);
- }
- else if(sapp_global_single.send_fake_pkt_mode == SEND_PKT_MODE_STACK_2_LAYER_1_ROUTE || sapp_global_single.send_fake_pkt_mode == SEND_PKT_MODE_STACK_2_LAYER_MUTI_ROUTE)
- {
- ether_type = net_layer_to_ethernet_protocol(low_layer_type);
- ret = packet_io_send_by_manual_conf(send_handle, datalen, dir, ether_type);
- }
- else
- {
- switch (low_layer_type)
- {
- case __ADDR_TYPE_IP_PAIR_V4:
- case ADDR_TYPE_IPV4:
- ret = packet_io_send_by_sys_routev4(send_handle, datalen, dir, feedback_buf, feedback_buf_len);
- break;
-
- case __ADDR_TYPE_IP_PAIR_V6:
- case ADDR_TYPE_IPV6:
- ret = packet_io_send_by_sys_routev6(send_handle, datalen, dir, feedback_buf, feedback_buf_len);
- break;
-
- default:
- /* ����ģʽ�µķ�IPЭ��, ����ʹ��ϵͳ·�ɷ���, ����ʹ��raw_eth_fdͨ��ָ���������� */
- ether_type = net_layer_to_ethernet_protocol(low_layer_type);
- ret = packet_io_send_by_manual_conf(send_handle, datalen, dir, ether_type);
- break;
- }
- }
- }
- else
- {
- ret = dl_io_fun_list.dl_io_low_level_send(send_handle->low_level_send_handle,
- (UINT8 *)send_handle->send_buf,
- datalen,
- low_layer_type,
- dir,
- thread_num);
- }
-
- return ret;
-}
-
-/*
- send_type:��������, RST, ��־, �ش����ݵ�;
- low_layer_type:��MAC��֮��, ��ײ�Э������, ��IPv4, ipv6, VLAN��.
- datalen :�ϲ�APP�ܳ�, ������MAC���14�ֽ�.
-*/
-int packet_io_send(MESA_send_handle *send_handle,int datalen,int send_type,
- int low_layer_type, int dir,int thread_num,
- char *feedback_buf, int *feedback_buf_len)
-{
- int ret = -1;
-
- switch(send_type){
- case SEND_TYPE_LINK_INJECT:
- ret = packet_io_send_fake_pkt(send_handle, datalen, send_type, low_layer_type,
- dir, thread_num, feedback_buf, feedback_buf_len);
- break;
-
- case SEND_TYPE_LOG:
- /* to do */
- ret = -1;
- break;
-
- case SEND_TYPE_REDIRECT:
- /* to do, ˮ�ԭʼ����ת�� */
- ret = -1;
- break;
-
- default:
- break;
- }
-
- return ret;
-}
-
-
-
-send_raw_pkt_info_t *get_raw_pkt_conf_by_id(unsigned int target_id)
-{
- int i;
-
- for(i = 0; i < G_SND_RAW_PKT_INFO_NUM; i++){
- if(target_id == G_SND_RAW_PKT_INFO[i].target_id){
- return &(G_SND_RAW_PKT_INFO[i]);
- }
- }
-
- //printf("Send raw pkt error! Not found target_id:%u\n", target_id);
-
- return NULL;
-}
-
-int parse_send_gdev_ip_conf(const char *profile_path)
-{
- FILE *fp;
- char conf_buf[1024] = "";
- int dev_id = 0;
- char ip_addr[32] = "";
- int ret = 0;
- fp = fopen(profile_path, "r");
- if(NULL == fp){
- printf("open %s error!\n", profile_path);
- return -1;
- }
-
- memset(g_send_gdev_ip_table, 0, sizeof(g_send_gdev_ip_table));
- G_SND_GDEV_INFO_NUM = 0;
-
- while(fgets(conf_buf, 1024, fp)){
- if('#' == conf_buf[0] || ' ' == conf_buf[0] || '\r' == conf_buf[0] || '\n' == conf_buf[0]){
- continue;
- }
-
- //del_last_rn(conf_buf, 1024);
-
- ret = sscanf(conf_buf, "%d\t%s", &dev_id, ip_addr);
-
- if(ret != 2 || dev_id >= 64 || strlen(ip_addr) >= 32)
- {
- printf("read %s error, line:%s!\n", profile_path, conf_buf);
- G_SND_GDEV_INFO_NUM = 0;
- break;
- }
-
- memcpy(g_send_gdev_ip_table[dev_id], ip_addr, strlen(ip_addr));
-
- G_SND_GDEV_INFO_NUM++;
- memset(conf_buf, 0, sizeof(conf_buf));
- }
- fclose(fp);
- return 0;
-}
-
-int parse_send_route_conf(const char *profile_path)
-{
- FILE *fp;
- char conf_buf[1024] = "";
- //const char *delim = "\t ";
- int dev_id = 0, link_id = 0;
- char mac_addr[18] = "";
- int ret = 0;
- fp = fopen(profile_path, "r");
- if(NULL == fp){
- printf("open %s error!\n", profile_path);
- return -1;
- }
-
- memset(g_send_gateway_mac_table, 0, sizeof(g_send_gateway_mac_table));
- G_SND_ROUTE_INFO_NUM = 0;
-
- while(fgets(conf_buf, 1024, fp)){
- if('#' == conf_buf[0] || ' ' == conf_buf[0] || '\r' == conf_buf[0] || '\n' == conf_buf[0]){
- continue;
- }
-
- //del_last_rn(conf_buf, 1024);
-
- ret = sscanf(conf_buf, "%d\t%d\t%s", &dev_id, &link_id, mac_addr);
-
- if(ret != 3 || dev_id >= 64 || link_id >= 16 || strlen(mac_addr) >= 18)
- {
- printf("read %s error, line:%s!\n", profile_path, conf_buf);
- G_SND_ROUTE_INFO_NUM = 0;
- break;
- }
-
- memcpy(g_send_gateway_mac_table[dev_id][link_id], mac_addr, strlen(mac_addr));
-
- G_SND_ROUTE_INFO_NUM++;
- memset(conf_buf, 0, sizeof(conf_buf));
- }
- fclose(fp);
- return 0;
-}
-
-static int parse_send_raw_pkt_conf(void)
-{
- FILE *fp;
- char conf_buf[1024];
- const char *delim = "\t ";
- char *saveptr;
- char *section;
-
- fp = fopen("conf/send_raw_pkt.conf", "r");
- if(NULL == fp){
- printf("open %s error!\n", "send_raw_pkt.conf");
- return -1;
- }
-
- while(fgets(conf_buf, 1024, fp)){
- if('#' == conf_buf[0] || ' ' == conf_buf[0] || '\r' == conf_buf[0] || '\n' == conf_buf[0]){
- continue;
- }
-
- del_last_rn(conf_buf, 1024);
-
- /* target_id */
- section = strtok_r(conf_buf, delim, &saveptr);
- if(NULL == section){
- return -1;
- }
- G_SND_RAW_PKT_INFO[G_SND_RAW_PKT_INFO_NUM].target_id = strtoul(section, NULL, 10);
-
- /* PAG args, net_card name */
- section = strtok_r(NULL, delim, &saveptr);
- if(NULL == section){
- return -1;
- }
- memcpy(G_SND_RAW_PKT_INFO[G_SND_RAW_PKT_INFO_NUM].send_args[CAP_MODEL_PAG].dev_name, section, 128);
-
- /* pcap args, device name */
- section = strtok_r(NULL, delim, &saveptr);
- if(NULL == section){
- return -1;
- }
- memcpy(G_SND_RAW_PKT_INFO[G_SND_RAW_PKT_INFO_NUM].send_args[CAP_MODEL_PCAP_ONLINE].dev_name, section, 128);
-
- /* PFRING args, net_card index */
- section = strtok_r(NULL, delim, &saveptr);
- if(NULL == section){
- return -1;
- }
- memcpy(G_SND_RAW_PKT_INFO[G_SND_RAW_PKT_INFO_NUM].send_args[CAP_MODEL_PFRING].dev_name, section, 128);
-
- /* DPDK args, port number */
- section = strtok_r(NULL, delim, &saveptr);
- if(NULL == section){
- return -1;
- }
- G_SND_RAW_PKT_INFO[G_SND_RAW_PKT_INFO_NUM].send_args[CAP_MODEL_DPDK].port_id = strtoul(section, NULL, 10);
-
- /* TODO 1, PPF args, port number */
- section = strtok_r(NULL, delim, &saveptr);
-
- /* TODO 1, PPF args, port number */
- section = strtok_r(NULL, delim, &saveptr);
-
- /* TODO 1, npacket args, port number */
- section = strtok_r(NULL, delim, &saveptr);
-
- /* TODO 1, qnf args, port number */
- section = strtok_r(NULL, delim, &saveptr);
-
- /* TODO 1, n95 args, port number */
- section = strtok_r(NULL, delim, &saveptr);
-
- while(strtok_r(NULL, delim, &saveptr)); /* clear line buf */
-
- G_SND_RAW_PKT_INFO_NUM++;
- }
-
- fclose(fp);
-
- return 0;
-}
-
-int packet_io_send_raw(int thread_num, char *data, int datalen,unsigned int target_id)
-{
- MESA_send_handle *snd_handle;
- send_raw_pkt_info_t *send_info;
- int ret;
-
- snd_handle = packet_io_get_send_handle(thread_num);
- if(NULL == snd_handle){
- return -1;
- }
-
- send_info = get_raw_pkt_conf_by_id(target_id);
- if(NULL == send_info){
- return -1;
- }
-
- ret = dl_io_fun_list.dl_io_raw_pkt_send(snd_handle->low_level_send_handle,
- (unsigned char *)data,
- datalen,
- &(send_info->send_args[g_packet_io_cap_mode]),
- thread_num);
- return ret;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-
+#include "common_io_dll.h"
+#include "packet_io.h"
+#include "packet_io_internal.h"
+#include "stream_manage.h"
+#include "stream_internal.h"
+#include "mesa_net.h"
+#include "sendpacket.h"
+#include "iknow.h"
+#include <MESA/MESA_handle_logger.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <sched.h>
+#include "MESA_feedback.h"
+
+/*
+2015-04-15
+ ƽ̨ʵʱ������������ݰ�, ��sizeָ����С, �������100MB,
+ ÿ���̷߳�Ϊ�����ļ�, ѭ��д��,
+ �������:
+ pid.thread_seq.[0-1].pcap,
+
+ 0�ļ�����100MB��ֹͣ, ת����ʼд1�ļ�, 1�ļ�Ҳ����100MB��, ����������д0�ļ�.
+
+ ͨ���ܿ��ؿ��ƴ˹����Ƿ���, ���鿴��ǰĿ¼�м���core, ��������д, ��ֹӲ����!
+
+ debug_pkt_dump_switch=1
+ debug_pkt_dump_max_num=5 //����core�ļ�
+ debug_pkt_dump_max_size_per_thread=100 // ��λMB
+
+ ����һ������, ��debug_pkt_dump,
+
+ sapp��ʼ��ʱ���߳���, ����THREAD_NUM���ܵ�, Ȼ��fork����, �ӽ��̱�Ϊdebug_pkt_dump,
+ �����̼�������sapp,
+
+ ��mesa_default_pkt_cb������, ���յ��İ�ͨ���ܵ�����debug_pkt_dump����.
+
+ debug_pkt_dump����, Ҳͬ������ͬ���߳�����������, д�ļ�.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+int gdev_init(void);
+extern int packet_io_status_init(void);
+extern MESA_send_handle g_send_handle[MAX_THREAD_NUM];
+char g_send_dev_name[DEV_NAME_STR_LEN]; /* ���������� */
+unsigned char g_send_dev_mac[MAC_ADDR_LEN];
+unsigned char g_send_gateway_mac[MAC_ADDR_LEN]; /* ͨ���ֹ����û��ѯ·�ɱ���ARP���õ� */
+unsigned char g_send_gateway_mac_table[64][16][18];
+static int G_SND_ROUTE_INFO_NUM = 0;
+
+unsigned char g_send_gdev_ip_table[64][32];
+static int G_SND_GDEV_INFO_NUM = 0;
+
+char g_up_dev_name[DEV_NAME_STR_LEN]; /* ����ģʽĬ�ϲ������� */
+char g_down_dev_name[DEV_NAME_STR_LEN];
+//static char g_cap_filter[CAP_FILTER_STR_LEN];
+//static int g_cap_buf_queue_num = 10000; /* IO�̺߳ʹ����߳�֮��Ļ�����г��� */
+int g_topology_mode = NET_CONN_PARALLEL;
+int g_packet_io_cap_mode = CAP_MODEL_PCAP_ONLINE;
+int g_packet_io_cap_level = CAP_LEVEL_MAC; /* ������ʼλ��,Ĭ��MAC�� */
+int g_packet_io_thread_num = 1;
+int g_app_send_rst_type;
+extern int g_packet_io_ipv6_switch;
+int g_packet_io_ipv6_raw_socket = 0; /* ���ڷ��ʹ�Ipv6 rst�� */
+extern int g_timestamp_record_sw;
+int g_encapsulate_with_ddp = 0; /* ʹ��DDPЭ���װ��ԭʼ�� */
+int g_encapsulate_with_L2E = 0; /* ʹ��DDPЭ���װ��x27ԭʼIP�� */
+ /*
+ 2015-12-10 lijia add, ����eth��, ���账��MAC��ַ, ���贴����ʱCOPY�����ṹ�� ,
+ ԭʼ����IP�㿪ʼ.
+ */
+int g_skip_ethernet_layer_sw = 0;
+void *g_packet_dl_send_handle[MAX_THREAD_NUM];/* ��̬IO��ķ������ */
+//static int g_packet_io_dir; /* ���ڼ�¼��ǰ��������, �����ʱʹ�� */
+int G_SKIP_NOT_IP_LAYER = 0; /* ������IPЭ��IJ�, ����˫ջ�������⻷����, RST������ */
+static int mesa_default_pkt_cb(const raw_pkt_t *p_raw_pkt, unsigned char dir, int thread_num);
+PACKET_IO_CB_T G_DEFAULT_PKT_CB = mesa_default_pkt_cb;
+
+dl_io_fun_list_t dl_io_fun_list;
+static int use_custom_pkt_cb = 0; /* �Ƿ������µ�callback���� */
+long long g_timedelay_threshold = 10000000; /* ��λCPU������, ��ʱ�� */
+
+int g_use_MESA_sleep_sw = 0;
+int g_raw_pkt_broken_check = 0; /* ���ԭʼ���Ƿ��޸� */
+static UINT8 *g_send_buf_pool[MAX_THREAD_NUM];
+
+#define MAX_RAW_PKT_TARGET_NUM (128)
+
+typedef struct{
+ unsigned int target_id; /* Ŀ��ID */
+ send_raw_args_t send_args[__CAP_MODEL_MAX];
+}send_raw_pkt_info_t;
+
+static send_raw_pkt_info_t G_SND_RAW_PKT_INFO[MAX_RAW_PKT_TARGET_NUM];
+static int G_SND_RAW_PKT_INFO_NUM = 0;
+
+void packet_io_exit(void);
+int packet_io_lib_load(int cap_mode);
+void del_last_rn(char *data, int max_len);
+static int parse_send_raw_pkt_conf(void);
+int parse_send_route_conf(const char *profile_path);
+int parse_send_gdev_ip_conf(const char *profile_path);
+extern void cycle_pkt_dump(int thread_seq, const raw_pkt_t *p_raw_pkt);
+extern char *MESA_MD5_sum_bin(unsigned char *raw_data, unsigned int raw_data_len, char result[16]);
+extern void timestamp_region_update(int tid, long long cpu_cycle);
+void pptp_exit(void);
+extern void ipv4_frag_per_thread_exit(int thread_seq);
+extern void ipv6_frag_per_thread_exit(int thread_seq);
+extern void pptp_per_thread_exit(int thread_seq);
+extern void __timestamp_print_max_tuple4(const raw_pkt_t *raw_pkt, long timedelay, int tid);
+
+static const unsigned char phony_feedback_eth_hdr_ip4[ETHERNET_HDR_LEN] =
+ {0x50, 0x48, 0x4F, 0x4E, 0x59, 0x5F, 0x4D, 0x41, 0x43, 0x41, 0x44, 0x44, 0x08, 0x00}; /* PHONY_MACADD + ipv4 */
+static const unsigned char phony_feedback_eth_hdr_ip6[ETHERNET_HDR_LEN] =
+ {0x50, 0x48, 0x4F, 0x4E, 0x59, 0x5F, 0x4D, 0x41, 0x43, 0x41, 0x44, 0x44, 0x86, 0xDD}; /* PHONY_MACADD + ipv6*/
+
+int packet_io_set_ipv6_module_enable(int op_switch)
+{
+ g_packet_io_ipv6_switch = op_switch;
+ return 0;
+}
+
+int packet_io_set_ipv6_raw_socket_enable(int op_switch)
+{
+ g_packet_io_ipv6_raw_socket = op_switch;
+ return 0;
+}
+
+int packet_io_register_cb(PACKET_IO_CB_T fun)
+{
+ int ret = 0;
+
+ use_custom_pkt_cb = 1;
+ if(dl_io_fun_list.dl_io_register_cb){
+ ret = dl_io_fun_list.dl_io_register_cb(fun);
+ }else{
+ printf("Warning, packet io library not support 'dl_io_register_cb'!\n");
+ }
+
+ return ret;
+}
+
+int packet_io_set_cap_level(int cap_level)
+{
+ int ret = 0;
+ g_packet_io_cap_level = cap_level;
+
+ if(dl_io_fun_list.dl_io_set_cap_level){
+ ret = dl_io_fun_list.dl_io_set_cap_level(cap_level);
+ }else{
+ printf("Warning, packet io library not support 'dl_io_set_cap_level'!\n");
+ }
+
+ return ret;
+}
+
+int packet_io_set_work_thread_num(int thread_num)
+{
+ int ret = 0;
+
+ if(dl_io_fun_list.dl_io_set_work_thread_num){
+ ret = dl_io_fun_list.dl_io_set_work_thread_num(thread_num);
+ }else{
+ printf("Warning, packet io library not support 'dl_io_set_work_thread_num'!\n");
+ }
+
+ g_packet_io_thread_num = thread_num;
+
+ return ret;
+}
+
+int packet_io_set_cap_mode(int cap_mode)
+{
+ int ret = 0;
+
+ if(dl_io_fun_list.dl_io_set_cap_mode){
+ ret = dl_io_fun_list.dl_io_set_cap_mode(cap_mode);
+ }else{
+ printf("Warning, packet io library not support 'dl_io_set_cap_mode'!\n");
+ }
+
+ return ret;
+}
+
+/*
+ Ϊ�˷����û����ã������ļ��е�ֵ�Ƚϼ򵥣���0��1��2��3�ȣ�
+ �ڴ��е�ֵ����Ƚϸ��ӣ���Ҫ�˺���ת��һ��.
+*/
+static int topology_mode_convert(int config_value)
+{
+ int private_value;
+
+ switch(config_value)
+ {
+ case 0:
+ private_value = NET_CONN_PARA_NOSEND;
+ break;
+
+ case 1:
+ private_value = NET_CONN_PARALLEL;
+ break;
+
+ case 2:
+ private_value = NET_CONN_SERIAL_2CARD;
+ break;
+
+ case 3:
+ private_value = NET_CONN_SERIAL_GDEV;
+ break;
+
+ default:
+ private_value = -1;
+ break;
+ }
+
+ return private_value;
+}
+
+int packet_io_set_topology_mode(int user_topology_mode)
+{
+ int private_top_mode, ret = -1;
+
+ private_top_mode = topology_mode_convert(user_topology_mode);
+ if(private_top_mode < 0){
+ return -1;
+ }
+
+ g_topology_mode = private_top_mode;
+
+ if(dl_io_fun_list.dl_io_set_topology_mode){
+ ret = dl_io_fun_list.dl_io_set_topology_mode(private_top_mode);
+ }else{
+ printf("Warning, packet io library not support 'dl_io_set_topology_mode'!\n");
+ }
+
+ return ret;
+}
+
+int packet_io_set_capdev_parallel(const char *cap_dev)
+{
+ int ret = 0;
+
+ if(dl_io_fun_list.dl_io_set_capdev_parallel){
+ ret = dl_io_fun_list.dl_io_set_capdev_parallel(cap_dev);
+ }else{
+ printf("Warning, packet io library not support 'dl_io_set_capdev_parallel'!\n");
+ }
+
+ strncpy(g_up_dev_name, cap_dev, DEV_NAME_STR_LEN);
+
+ return ret;
+}
+
+int packet_io_set_capdev_serial(const char *up_dev, const char *down_dev)
+{
+ int ret = 0;
+
+ if(dl_io_fun_list.dl_io_set_capdev_serial){
+ ret = dl_io_fun_list.dl_io_set_capdev_serial(up_dev, down_dev);
+ }else{
+ printf("Warning, packet io library not support 'dl_io_set_capdev_serial'!\n");
+ }
+
+ strncpy(g_up_dev_name, up_dev, DEV_NAME_STR_LEN);
+ strncpy(g_down_dev_name, down_dev, DEV_NAME_STR_LEN);
+
+ return ret;
+}
+
+int packet_io_set_send_dev(const char *send_dev)
+{
+ int ret;
+
+ ret = snprintf(g_send_dev_name, DEV_NAME_STR_LEN, "%s", send_dev);
+ if(ret >= DEV_NAME_STR_LEN){
+ printf("send device name is too long!\n");
+ return -1;
+ }
+
+ return ret;
+}
+
+int packet_io_set_gateway_mac(const char *gateway_mac)
+{
+ if(MESA_mac_pton(gateway_mac, ':', (char *)g_send_gateway_mac) < 0){
+ printf("error, gateway mac:%s is not correct, for example:00:11:22:33:44:55\n", gateway_mac);
+ return -1;
+ }
+
+ return 0;
+}
+
+int packet_io_set_capture_filter(const char *filter_rule)
+{
+ int ret = 0;
+
+ if(dl_io_fun_list.dl_io_set_capture_filter){
+ ret = dl_io_fun_list.dl_io_set_capture_filter(filter_rule);
+ }else{
+ printf("Warning, packet io library not support 'dl_io_set_capture_filter'!\n");
+ }
+
+ return ret;
+}
+
+
+long packet_io_get_app_drop_num(int thread_num)
+{
+ long ret = 0;
+
+ if(dl_io_fun_list.dl_io_get_app_drop_num){
+ ret = dl_io_fun_list.dl_io_get_app_drop_num(thread_num);
+ }else{
+ printf("Warning, packet io library not support 'dl_io_get_app_drop_num'!\n");
+ }
+
+ return ret;
+}
+
+
+long packet_io_get_app_drop_num_tot(void)
+{
+ int i;
+ long ret = 0;
+
+ for(i = 0; i < g_packet_io_thread_num; i++){
+ ret += packet_io_get_app_drop_num(i);
+ }
+
+ return 0;
+}
+
+long packet_io_get_lib_drop_num(void)
+{
+ long ret = 0;
+
+ if(dl_io_fun_list.dl_io_get_lib_drop_num){
+ ret = dl_io_fun_list.dl_io_get_lib_drop_num();
+ }else{
+ printf("Warning, packet io library not support 'dl_io_get_lib_drop_num'!\n");
+ }
+
+ return ret;
+}
+
+int packet_io_set_cap_buf_queue(int queue_num_max)
+{
+ int ret = 0;
+
+ if(dl_io_fun_list.dl_io_set_cap_buf_queue){
+ ret = dl_io_fun_list.dl_io_set_cap_buf_queue(queue_num_max);
+ }else{
+ printf("Warning, packet io library not support 'dl_io_set_cap_buf_queue'!\n");
+ }
+
+ return ret;
+}
+
+static int packet_io_process_ddp_pkt(const MESA_feedback_raw_pkt_t *ddp_fix_hdr,
+ int ddp_payload_len, raw_pkt_t *p_raw_pkt, unsigned char dir, int thread_num)
+{
+ const char *ddp_payload;
+ //int pkt_index = 1; //�����ݲ�֧��DDP�ۺ�ԭʼ��
+ if(MESA_FEEDBACK_HDR_MAGIC != ddp_fix_hdr->property_hdr.magic){
+ return PASS;
+ }
+
+ if(0 != ddp_fix_hdr->property_hdr.stream){
+ return PASS;
+ }
+
+ if((MESA_FEEDBACK_DTYPE_IPv4 != ddp_fix_hdr->property_hdr.data_type)
+ && (MESA_FEEDBACK_DTYPE_IPv6 != ddp_fix_hdr->property_hdr.data_type)){
+ return PASS;
+ }
+
+ ddp_payload = (const char *)((char *)ddp_fix_hdr + sizeof(MESA_feedback_raw_pkt_t));
+
+#if 0 /* �������Զ����0, ͨ��IPͷ��ȡ�İ�������ʵ�ʲ���, ����Ҳ��֧��VLAN, PPPOE�����ݰ�, �����ݲ�֧��DDP�ۺ�ԭʼ��, һ��DDP��ֻȡһ��ԭʼ�� */
+ while(ddp_payload_len > 0)
+ {
+ p_raw_pkt->raw_pkt_len = get_pkt_len_from_eth_hdr((const struct mesa_ethernet_hdr *)ddp_payload);
+ if(p_raw_pkt->raw_pkt_len < 0){
+ sapp_runtime_log(30, "ddp raw pkt parse error, pkt index:%d\n", pkt_index);
+ break;
+ }
+#else
+ {
+ p_raw_pkt->raw_pkt_len = ddp_payload_len;
+#endif
+ p_raw_pkt->raw_pkt_data = (char *)ddp_payload;
+#if CYCLE_PKT_DUMP
+ /* 2017-10-09 lijia add, for tcpdump_mesa capture ddp inner packet */
+ cycle_pkt_dump(thread_num, p_raw_pkt);
+#endif
+ eth_entry(NULL, p_raw_pkt->raw_pkt_data, thread_num, dir, p_raw_pkt, 0);
+
+#if 0
+ ddp_payload += p_raw_pkt->raw_pkt_len;
+ ddp_payload_len -= p_raw_pkt->raw_pkt_len;
+ if(ddp_payload_len < 0){
+ sapp_runtime_log(30, "ddp raw pkt parse error, pkt index:%d\n", pkt_index);
+ break;
+ }
+ pkt_index++;
+#endif
+ }
+
+ return PASS;
+}
+
+static int packet_io_strip_ddp_hdr(const raw_pkt_t *p_raw_pkt, unsigned char dir, int thread_num)
+{
+ int ret;
+ const MESA_feedback_raw_pkt_t *ddp_raw_pkt_hdr = NULL;
+ int ddp_payload_len = p_raw_pkt->raw_pkt_len; /* DDP���ݳ���, ���������ڲ����ddpͷ���͸��� */
+
+ switch(p_raw_pkt->low_layer_type){
+ case CAP_LEVEL_MAC:
+ {
+ const struct mesa_ethernet_hdr *ethh = (const struct mesa_ethernet_hdr *)p_raw_pkt->raw_pkt_data;
+ if(ETHERTYPE_IP == ntohs(ethh->ether_type)){
+ const struct mesa_ip4_hdr *ip4h = (const struct mesa_ip4_hdr *)((char *)ethh + sizeof(struct mesa_ethernet_hdr));
+ ddp_raw_pkt_hdr = (const MESA_feedback_raw_pkt_t *)((char *)ip4h + ip4h->ip_hl * 4 + sizeof(struct mesa_udp_hdr));
+ ddp_payload_len -= sizeof(struct mesa_ethernet_hdr) + sizeof(struct mesa_ip4_hdr) + sizeof(struct mesa_udp_hdr) + sizeof(MESA_feedback_raw_pkt_t);
+ }else{
+ /* �ݲ�֧��������ʽ��DDPԭʼ���ش� */
+ sapp_runtime_log(30, "ddp raw pkt parse error, unknown ether_type:0x%x\n", ntohs(ethh->ether_type));
+ return PASS;
+ }
+ }
+ break;
+
+ case CAP_LEVEL_IPV4:
+ {
+ const struct mesa_ip4_hdr *ip4h = (const struct mesa_ip4_hdr *)p_raw_pkt->raw_pkt_data;
+ ddp_raw_pkt_hdr = (const MESA_feedback_raw_pkt_t *)((char *)ip4h + ip4h->ip_hl * 4 + sizeof(struct mesa_udp_hdr));
+ ddp_payload_len -= sizeof(struct mesa_ip4_hdr) + sizeof(struct mesa_udp_hdr) + sizeof(MESA_feedback_raw_pkt_t);
+ }
+ break;
+
+ default:
+ return PASS;
+ break;
+ }
+
+ ret = packet_io_process_ddp_pkt(ddp_raw_pkt_hdr, ddp_payload_len, (raw_pkt_t *)p_raw_pkt, dir, thread_num);
+
+ return ret;
+}
+
+
+#if 1 /* for xx7 �ӿ� */
+
+typedef struct {
+ uint32_t magic_num;
+ uint8_t version;
+ uint8_t msg_type;
+ uint16_t flag;
+ uint32_t cont_len; /* ������ͷ����12�ֽ�! */
+}L2E_msg_header_t; /*sizeof = 12B */
+
+
+
+typedef struct {
+ uint16_t data_len; /* ������ͷ����4�ֽ� */
+ uint16_t data_type;
+ uint8_t data_value[0];
+}L2E_data_small_block_hdr_t;
+
+struct __msg_small_body_t{
+ uint32_t cap_ip; // ǰ�˽ڵ�IP
+ uint32_t data_id; // �����н����Ψһ���
+ uint16_t unit_num; //С���ݿ�ĸ���
+ L2E_data_small_block_hdr_t small_unit[0]; //С���ݿ�����
+}__attribute__((packed));
+typedef struct __msg_small_body_t L2E_msg_small_body_hdr_t;
+
+
+#endif
+
+/*
+ 3x7��Ŀ�ش���ԭʼ��ͷ��.
+*/
+static int packet_io_strip_L2E_hdr(raw_pkt_t *p_raw_pkt, unsigned char dir, int thread_num)
+{
+ int ret;
+#define L2E_HDR_TOTAL_LEN (78)
+#define L2E_PKT_HDR_MAGIC 0xD0BADABA
+ const struct mesa_ethernet_hdr *ethh = (const struct mesa_ethernet_hdr *)p_raw_pkt->raw_pkt_data;
+ const unsigned int *l2e_hdr_magic;
+ unsigned char *L2E_payload;
+ int L2E_len;
+ const L2E_msg_header_t *L2E_msg_hdr;
+ const L2E_data_small_block_hdr_t *small_block_hdr;
+ const L2E_msg_small_body_hdr_t *small_block_body;
+ int i;
+
+ /* һЩ������ */
+ if(ntohs(ethh->ether_type) != ETHERTYPE_IP){
+ return PASS;
+ }
+
+ const struct mesa_ip4_hdr *ip4h = (const struct mesa_ip4_hdr *)((char *)p_raw_pkt->raw_pkt_data + sizeof(struct mesa_ethernet_hdr));
+ if(ip4h->ip_p != IPPROTO_UDP){
+ return PASS;
+ }
+
+ if(ntohs(ip4h->ip_len) < sizeof(struct mesa_ip4_hdr)/* �����ipͷ */ + sizeof(struct mesa_udp_hdr)/* ���udpͷ */ + L2E_HDR_TOTAL_LEN + sizeof(struct mesa_ip4_hdr)/* �ڲ�IP��ͷ */){
+ return PASS;
+ }
+
+ L2E_payload = (unsigned char *)p_raw_pkt->raw_pkt_data + sizeof(struct mesa_ethernet_hdr) + sizeof(struct mesa_ip4_hdr) + sizeof(struct mesa_udp_hdr);
+ L2E_len = p_raw_pkt->raw_pkt_len - sizeof(struct mesa_ethernet_hdr) - sizeof(struct mesa_ip4_hdr) - sizeof(struct mesa_udp_hdr);
+
+ while(L2E_len > 0){
+ L2E_msg_hdr = (L2E_msg_header_t *)L2E_payload;
+ if(L2E_msg_hdr->magic_num != L2E_PKT_HDR_MAGIC){
+ sapp_runtime_log(20, "L2E hdr error, magic is:%x\n", L2E_msg_hdr->magic_num);
+ return PASS;
+ }
+
+ L2E_payload += sizeof(L2E_msg_header_t);
+ L2E_len -= sizeof(L2E_msg_header_t);
+
+ if(L2E_len < (int)L2E_msg_hdr->cont_len ){
+ sapp_runtime_log(20, "L2E hdr error, left payload len is %d, smaller than hdr declare len:%d!\n", L2E_len, L2E_msg_hdr->cont_len);
+ return PASS;
+ }
+
+ if(L2E_msg_hdr->msg_type != 2){ /* 1:meta data; 2:small block; 3:big block, ֻ����С�������е�IP��, ��������������! */
+ L2E_payload += L2E_msg_hdr->cont_len;
+ L2E_len -= L2E_msg_hdr->cont_len;
+ continue;
+ }
+
+ small_block_body = (L2E_msg_small_body_hdr_t *)L2E_payload;
+ L2E_payload += sizeof(L2E_msg_small_body_hdr_t);
+ L2E_len -= sizeof(L2E_msg_small_body_hdr_t);
+
+ for(i = 0; i < small_block_body->unit_num; i++){
+ small_block_hdr = (L2E_data_small_block_hdr_t *)L2E_payload;
+ if(small_block_hdr->data_type != 0x0002){ /* 0x0002: ԭʼIP�� */
+ L2E_payload += small_block_hdr->data_len;
+ L2E_len -= small_block_hdr->data_len;
+ continue;
+ }
+
+ /* ����raw_pktָ�� */
+ p_raw_pkt->raw_pkt_data = L2E_payload + sizeof(L2E_data_small_block_hdr_t);
+ p_raw_pkt->raw_pkt_len = small_block_hdr->data_len - sizeof(L2E_data_small_block_hdr_t);
+ p_raw_pkt->low_layer_type = ADDR_TYPE_IPV4;
+#if CYCLE_PKT_DUMP
+ /* for tcpdump_mesa capture ddp inner packet */
+ cycle_pkt_dump(thread_num, p_raw_pkt);
+#endif
+ ret = ipv4_entry(NULL, p_raw_pkt->raw_pkt_data, thread_num, dir, p_raw_pkt, 0);
+
+ L2E_payload += small_block_hdr->data_len;
+ L2E_len -= small_block_hdr->data_len;
+ }
+ }
+
+ return ret;
+}
+extern void sapp_fs2_set_latency(int thead_seq, long long time_cost);
+
+static int mesa_default_pkt_cb(const raw_pkt_t *p_raw_pkt, unsigned char dir, int thread_num)
+{
+ int ret = PASS;
+ long long before_call = 0, after_call, timecost;
+
+ struct timespec start, end;
+
+ clock_gettime(CLOCK_MONOTONIC, &start);
+ //before_call = sapp_get_cpu_cycle();
+
+#if DEBUG
+ char raw_pkt_md5_before[16];
+ char raw_pkt_md5_after[16];
+
+ if(unlikely(g_raw_pkt_broken_check != 0)){
+ MESA_MD5_sum_bin((unsigned char *)p_raw_pkt->raw_pkt_data, p_raw_pkt->raw_pkt_len, raw_pkt_md5_before);
+ }
+#endif
+
+ if(unlikely(g_encapsulate_with_ddp)){
+ /* ����ddp���װ���ܺ�, ��packet_io_process_ddp_pkt()�����в���DDP�������� */
+ ret = packet_io_strip_ddp_hdr(p_raw_pkt, dir, thread_num);
+ } else if(unlikely(g_encapsulate_with_L2E)){
+ ret = packet_io_strip_L2E_hdr((raw_pkt_t *)p_raw_pkt, dir, thread_num);
+ }else{
+
+#if CYCLE_PKT_DUMP
+ cycle_pkt_dump(thread_num, p_raw_pkt);
+#endif
+ switch(p_raw_pkt->low_layer_type){
+ case CAP_LEVEL_MAC:
+ ret = eth_entry(NULL,p_raw_pkt->raw_pkt_data,thread_num,dir, p_raw_pkt, 0);
+ break;
+
+ case CAP_LEVEL_IPV4:
+ ret = ipv4_entry(NULL,(void *)p_raw_pkt->raw_pkt_data,thread_num,dir, p_raw_pkt, 0);
+ break;
+
+ case CAP_LEVEL_IPV6:
+ ret = ipv6_entry(NULL,(void *)p_raw_pkt->raw_pkt_data,thread_num,dir, p_raw_pkt, 0);
+ break;
+
+ default:
+ return PASS;
+ break;
+ }
+ }
+
+ //after_call = sapp_get_cpu_cycle();
+ //timecost = after_call - before_call;
+ clock_gettime(CLOCK_MONOTONIC, &end);
+ timecost = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_nsec - start.tv_nsec);
+ timestamp_region_update(thread_num, timecost);
+ sapp_fs2_set_latency(thread_num, timecost);
+
+#if DEBUG
+ if(unlikely(g_timestamp_record_sw)){
+ if(timecost > g_timedelay_threshold){
+ __timestamp_print_max_tuple4(p_raw_pkt, timecost, thread_num);
+ }
+ }
+
+ if(unlikely(g_raw_pkt_broken_check != 0)){
+ MESA_MD5_sum_bin((unsigned char *)p_raw_pkt->raw_pkt_data, p_raw_pkt->raw_pkt_len, raw_pkt_md5_after);
+
+ if(memcmp(raw_pkt_md5_before, raw_pkt_md5_after, 16) != 0){
+ printf("\033[41mraw packet is broken involuntarily! If you don't care, please disable 'raw_pkt_broken_check' in main.conf!\033[0m\n");
+ abort();
+ }
+ }
+#endif
+
+ return ret;
+}
+
+
+void packet_io_exit(void)
+{
+ /* ����ģʽ��, �������߳�һЩʱ��, ����δ�������, ����MESA_tcp�첽�������ݵȵ�. */
+ sched_yield();
+ sleep(1);
+ sched_yield();
+ sleep(1);
+
+ exit(1);
+
+ return;
+}
+
+int packet_io_init(int argc, char *argv[])
+{
+ int i;
+
+ if(0 == use_custom_pkt_cb){
+ packet_io_register_cb(mesa_default_pkt_cb);
+ }
+
+ if(NULL == dl_io_fun_list.dl_io_init){
+ printf("Error, packet io library must support 'dl_io_init' !\n");
+ exit(0);
+ }
+
+ if(dl_io_fun_list.dl_io_init(argc, argv) < 0){
+ return -1;
+ }
+
+ for(i = 0; i < MAX_THREAD_NUM; i++){
+ g_send_buf_pool[i] = (UINT8 *)malloc(SENDPACKET_BUF_LEN);
+ }
+
+ if(sendpacket_init_new(g_packet_io_thread_num) < 0){
+ printf("Error, sendpacket_init_new error !\n");
+ return -1;
+ }
+
+#if 0 /* 20161117 lijia move to send_handle_init() */
+ for(i = 0; i < g_packet_io_thread_num; i++){
+ g_packet_dl_send_handle[i] = dl_io_fun_list.dl_io_get_send_handle(i);
+ }
+#endif
+
+ if(CAP_MODEL_PCAP_DUMPFILE == g_packet_io_cap_mode){
+ dl_io_fun_list.dl_io_register_exit_cb(packet_io_exit);
+ }
+
+ if(g_send_dev_name[0] != '\0'){
+ if(MESA_get_dev_mac(g_send_dev_name, g_send_dev_mac) < 0){
+ printf("Warning, can't get %s mac addr!\n", g_send_dev_name);
+ }
+ }else{
+ printf("Warning, not assign send device!\n");
+ }
+
+ gdev_init();
+
+ parse_send_gdev_ip_conf("conf/send_gdev.conf");
+
+ parse_send_route_conf("conf/send_route.conf");
+
+ parse_send_raw_pkt_conf();
+
+ packet_io_status_init();
+
+ return 0;
+}
+
+extern int g_StreamTcpAllFunNum;
+extern int g_Ipv6FunNum;
+extern int app_function_rationality_check(void);
+ /* not return until error, or use 'CAP_MODEL_PCAP_DUMPFILE' mode */
+void packet_io_run(void)
+{
+ pthread_t pid;
+ if(NULL == dl_io_fun_list.dl_io_run){
+ printf("Error, packet io library must support 'dl_io_run' !\n");
+ sapp_runtime_log(RLOG_LV_FATAL, "%s:%d: Error, packet io library must support 'dl_io_run' !\n", __FILE__, __LINE__);
+ assert(0);
+ }
+
+ app_function_rationality_check();
+
+ pthread_create(&pid, NULL, time_event_thread ,NULL);
+
+ dl_io_fun_list.dl_io_run();
+
+ while(1){
+ pause();
+ }
+}
+
+extern volatile int update_packet_io_status_sw;
+void packet_io_clean_thread_context(int thread_seq)
+{
+ if(1 == update_packet_io_status_sw){
+ sysinfo_output(); /* ���һ��дͳ����Ϣ, �رձ�־λ, ��Ϊ�����������, ��д��û������ */
+ update_packet_io_status_sw = 0;
+ }
+
+ free_thread_stream(thread_seq);
+
+ ipv4_frag_per_thread_exit(thread_seq);
+ ipv6_frag_per_thread_exit(thread_seq);
+ pptp_per_thread_exit(thread_seq);
+}
+
+
+MESA_send_handle *packet_io_get_send_handle(int thread_id)
+{
+ return &g_send_handle[thread_id];
+}
+
+
+unsigned char *packet_io_get_sendbuf(int type, int thread_num)
+{
+ if(g_topology_mode & __NET_CONN_PARALLEL){
+ return g_send_buf_pool[thread_num];
+ }
+
+ return dl_io_fun_list.dl_io_get_sendbuf(g_packet_dl_send_handle[thread_num], thread_num);
+}
+
+void packet_io_free_sendbuf(int type, int thread_num)
+{
+ if(g_topology_mode & __NET_CONN_PARALLEL){
+ return; /* use static global variable, do nothing */
+ }
+
+ dl_io_fun_list.dl_io_free_sendbuf(g_packet_dl_send_handle[thread_num], thread_num);
+ return;
+}
+
+
+static int packet_io_calc_ethernet_offset_to_ip(const unsigned char *sendbuf)
+{
+ int offset;
+ const struct mesa_ethernet_hdr *outer_ehdr;
+ ///const struct mesa_ethernet_hdr *inner_ehdr;
+
+ if(sapp_global_single.send_fake_pkt_mode == SEND_PKT_MODE_GDEV){
+ sendbuf += VXLAN_HDR_RESERVED_LEN; /* vxlanģʽ��Ԥ����vxlan�����mac,ip,udpͷ��, ��ת���ڲ�macͷ */
+ }
+
+ switch(g_packet_io_cap_level){
+ case CAP_LEVEL_IPV4:
+ offset = 0;
+ break;
+
+ case CAP_LEVEL_MAC:
+ outer_ehdr = (struct mesa_ethernet_hdr *)sendbuf;
+ if(ETHERTYPE_PANGU_MAC_IN_MAC == ntohs(outer_ehdr->ether_type)){
+ offset = MAC_IN_MAC_HDR_LEN;
+ }else{
+ offset = sizeof(struct mesa_ethernet_hdr);
+ }
+ break;
+
+ default:
+ offset = -1;
+ sapp_runtime_log(RLOG_LV_FATAL, "MESA_kill_tcp: Invalid cap_mode:%d\n", g_packet_io_cap_level);
+ return -1;
+ }
+
+ return offset;
+}
+
+static int packet_io_send_by_sys_routev4(MESA_send_handle *send_handle,int datalen,int dir,
+ char *feedback_buf, int *feedback_buf_len)
+{
+ int ret, offset = 0;
+ struct sockaddr_in sock_addr_v4;
+ char *actual_data_ptr;
+ struct mesa_ip4_hdr *ip4_hdr;
+
+ offset = packet_io_calc_ethernet_offset_to_ip(send_handle->send_buf);
+ if(offset < 0){
+ return -1;
+ }
+
+ /* ʹ��ϵͳ·��ʱ, MAC��ַ��Э��ջ���, ָ��ͳ���Ҫ��ȥETHͷ�� */
+#if 0
+ actual_data_ptr = (char *)send_handle->send_buf + sizeof(mesa_ethernet_hdr);
+ datalen -= sizeof(mesa_ethernet_hdr);
+#else
+ actual_data_ptr = (char *)send_handle->send_buf + offset;
+ datalen -= offset;
+
+#endif
+
+ ip4_hdr = (struct mesa_ip4_hdr *)actual_data_ptr;
+
+ memset(&sock_addr_v4, 0, sizeof(struct sockaddr_in));
+ sock_addr_v4.sin_family = AF_INET;
+ /* build_ipv4ʱ�Ѿ���dir������õ�ַ, �˴�ֱ��ʹ��ip_dst���� */
+ sock_addr_v4.sin_addr.s_addr = ip4_hdr->ip_dst.s_addr;
+
+ //if(sapp_global_single.send_fake_pkt_mode != 0){
+ // return packet_io_send_fake_pkt_by_gdev(send_handle, ADDR_TYPE_IPV4,
+ // actual_data_ptr+VXLAN_HDR_RESERVED_LEN, datalen, dir,
+ // feedback_buf, feedback_buf_len);
+ //}
+
+retry:
+ ret = sendto(send_handle->raw_ipv4_fd, actual_data_ptr, datalen, 0,
+ (struct sockaddr *)&sock_addr_v4, sizeof(struct sockaddr));
+ if(ret < 0){
+ if(EINTR == errno){
+ goto retry; /* ���ź��жϵ�IO������Ҫ���� */
+ }else{
+ g_SysInputInfo[send_handle->threadnum][SEND_PKT_ERR]++;
+ g_SysInputInfo[send_handle->threadnum][SEND_PKT_ERR_LEN] += datalen;
+ sapp_runtime_log(RLOG_LV_FATAL, "%s:%d: sendto error, %s\n", __FILE__,__LINE__,strerror(errno));
+ return ret;
+ }
+ }
+
+ /* �Ƿ���Ҫ��Inject�������������� */
+ if(feedback_buf != KILL_TCP_PHONY_POINTER){
+ if(*feedback_buf_len < ret + (int)sizeof(struct mesa_ethernet_hdr)){
+ return -2;
+ }
+
+ memcpy(feedback_buf, phony_feedback_eth_hdr_ip4, ETHERNET_HDR_LEN);
+
+ memcpy(feedback_buf + sizeof(struct mesa_ethernet_hdr), actual_data_ptr, datalen);
+
+ *feedback_buf_len = datalen + sizeof(struct mesa_ethernet_hdr);
+ }
+
+ return ret;
+}
+
+static int packet_io_send_by_sys_routev6(MESA_send_handle *send_handle,int datalen,int dir,
+ char *feedback_buf, int *feedback_buf_len)
+{
+ int ret;
+ struct sockaddr_in6 sock_addr_v6;
+ char *actual_data_ptr;
+ struct mesa_ip6_hdr *ip6_hdr;
+ int offset;
+
+ if(0 == g_packet_io_ipv6_raw_socket){
+ printf("IPv6 module is not support! Please check 'main.conf->IPv6_raw_socket'.\n");
+ sapp_runtime_log(RLOG_LV_FATAL, "%s:%d: IPv6 module is not support! Please check 'main.conf->IPv6_raw_socket'.\n", __FILE__, __LINE__);
+ return -1;
+ }
+
+ offset = packet_io_calc_ethernet_offset_to_ip(send_handle->send_buf);
+ if(offset < 0){
+ return -1;
+ }
+
+ /* ʹ��ϵͳ·��ʱ, MAC��ַ��Э��ջ���, ָ��ͳ���Ҫ��ȥETHͷ�� */
+#if 0
+ actual_data_ptr = (char *)send_handle->send_buf + sizeof(struct mesa_ethernet_hdr);
+ datalen -= sizeof(struct mesa_ethernet_hdr);
+#else
+ /* 2018-09-13 lijia modify, adjust MAC_IN_MAC header */
+ actual_data_ptr = (char *)send_handle->send_buf + offset;
+ datalen -= offset;
+#endif
+
+ ip6_hdr = (struct mesa_ip6_hdr *)actual_data_ptr;
+
+ memset(&sock_addr_v6, 0, sizeof(struct sockaddr_in6));
+ sock_addr_v6.sin6_family = AF_INET6;
+ memcpy(sock_addr_v6.sin6_addr.s6_addr, ip6_hdr->ip6_dst.s6_addr, IPV6_ADDR_LEN);
+
+retry:
+ ret = sendto(send_handle->raw_ipv6_fd, actual_data_ptr, datalen, 0,
+ (struct sockaddr *)&sock_addr_v6, sizeof(struct sockaddr_in6));
+ if(ret < 0){
+ if(EINTR == errno){
+ goto retry; /* ���ź��жϵ�IO������Ҫ���� */
+ }else{
+ g_SysInputInfo[send_handle->threadnum][SEND_PKT_ERR]++;
+ g_SysInputInfo[send_handle->threadnum][SEND_PKT_ERR_LEN] += datalen;
+ sapp_runtime_log(RLOG_LV_FATAL,"%s:%d: packet_io_send_by_sys_routev6() sendto error, %s\n", __FILE__,__LINE__,strerror(errno));
+ return ret;
+ }
+ }
+
+ if(feedback_buf != KILL_TCP_PHONY_POINTER){
+ if(*feedback_buf_len < ret + (int)sizeof(struct mesa_ethernet_hdr)){
+ return -2;
+ }
+
+ memcpy(feedback_buf, phony_feedback_eth_hdr_ip6, ETHERNET_HDR_LEN);
+
+ memcpy(feedback_buf + sizeof(struct mesa_ethernet_hdr), actual_data_ptr, datalen);
+ *feedback_buf_len = datalen + sizeof(struct mesa_ethernet_hdr);
+ }
+
+ return ret;
+}
+
+static int packet_io_get_sendroute_mac(char dev_id, char link_id, unsigned char *out_mac_addr)
+{
+ char *p_mac_addr = (char *)g_send_gateway_mac_table[dev_id][link_id];
+ if(G_SND_ROUTE_INFO_NUM <= 0 || strlen(p_mac_addr) <= 0)return -1;
+ else
+ {
+ if(MESA_mac_pton(p_mac_addr, ':', (char *)out_mac_addr) < 0){
+ printf("error, src mac:%s is not correct, for example:00:11:22:33:44:55\n", p_mac_addr);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int packet_io_send_by_manual_conf(MESA_send_handle *send_handle,int datalen,
+ int dir, UINT16 ether_type)
+{
+ int ret;
+
+ /* to do:
+ ��ȡ����ip, mac ��Ϣ,
+ �����ֹ�����,
+ ����ݷ���/proc/net/route, /proc/net/arp�Զ���ȡ!
+
+ get_gateway_info_by_manual();
+ get_gateway_info_aotu();
+
+ */
+
+#if 0 /* for test, use 10.0.6.201 mac addr */
+ static char mac_201_gateway[6] = {0xdc, 0xd2, 0xfc, 0x66, 0xec, 0xb2};
+ static char mac_201_em2[6] = {0x74, 0x86,0x7A,0xD0,0x12,0xFD};
+
+ memcpy(g_send_gateway_mac, mac_201_gateway, 6);
+ memcpy(g_send_dev_mac, mac_201_em2, 6);
+
+#endif
+ const struct streaminfo_private *pstrem_pr = (const struct streaminfo_private *)send_handle->user_arg;
+ const struct streaminfo *pstream = (const struct streaminfo *)send_handle->user_arg;
+ const struct streaminfo *tmpstream = pstream;
+ struct vxlan_info mim_mem_hdr;
+ int opt_len = sizeof(mim_mem_hdr);
+ ret = MESA_get_stream_opt(tmpstream, MSO_STREAM_VXLAN_INFO, &mim_mem_hdr, &opt_len);
+ if(ret < 0){
+ sapp_runtime_log(20, "packet_io_send_by_manual_conf(): get vxlan info error!\n");
+ return -1;
+ }
+ unsigned char send_route_mac[MAC_ADDR_LEN] = "";
+ unsigned char *p_dst_mac;
+
+ if(sapp_global_single.send_fake_pkt_mode == SEND_PKT_MODE_STACK_2_LAYER_MUTI_ROUTE )
+ {
+ ret = packet_io_get_sendroute_mac(mim_mem_hdr.dev_id, mim_mem_hdr.link_id, send_route_mac);
+ if(ret < 0){
+ sapp_runtime_log(20, "packet_io_send_by_manual_conf(): get sendroute_mac info using %d:%d error!\n", mim_mem_hdr.dev_id, mim_mem_hdr.link_id);
+ return -1;
+ }
+ p_dst_mac = send_route_mac;
+ }
+ else
+ {
+ p_dst_mac = g_send_gateway_mac;
+ }
+ sendpacket_build_ethernet(p_dst_mac, g_send_dev_mac, ether_type, NULL, 0, send_handle->send_buf);
+
+send_again:
+ ret = sendto(send_handle->raw_eth_fd, send_handle->send_buf, datalen, 0,
+ (struct sockaddr *)&send_handle->saddr_raw_eth, sizeof(struct sockaddr));
+ if(ret < 0){
+ if((EAGAIN == errno) || (EINTR == errno) ){
+ goto send_again;
+ }else{
+ return -1;
+ }
+ }
+
+ return ret;
+}
+
+int packet_io_send_fake_pkt(MESA_send_handle *send_handle,int datalen,int send_type,
+ int low_layer_type, int dir,int thread_num,
+ char *feedback_buf, int *feedback_buf_len)
+{
+ int ret;
+ UINT16 ether_type;
+
+ if(g_topology_mode & __NET_CONN_PARALLEL)
+ {
+ if(sapp_global_single.send_fake_pkt_mode == SEND_PKT_MODE_GDEV)
+ {
+ ret = packet_io_send_fake_pkt_by_gdev(send_handle, (enum addr_type_t)low_layer_type,
+ (char *)send_handle->send_buf, datalen, dir, feedback_buf, feedback_buf_len);
+ }
+ else if(sapp_global_single.send_fake_pkt_mode == SEND_PKT_MODE_STACK_2_LAYER_1_ROUTE || sapp_global_single.send_fake_pkt_mode == SEND_PKT_MODE_STACK_2_LAYER_MUTI_ROUTE)
+ {
+ ether_type = net_layer_to_ethernet_protocol(low_layer_type);
+ ret = packet_io_send_by_manual_conf(send_handle, datalen, dir, ether_type);
+ }
+ else
+ {
+ switch (low_layer_type)
+ {
+ case __ADDR_TYPE_IP_PAIR_V4:
+ case ADDR_TYPE_IPV4:
+ ret = packet_io_send_by_sys_routev4(send_handle, datalen, dir, feedback_buf, feedback_buf_len);
+ break;
+
+ case __ADDR_TYPE_IP_PAIR_V6:
+ case ADDR_TYPE_IPV6:
+ ret = packet_io_send_by_sys_routev6(send_handle, datalen, dir, feedback_buf, feedback_buf_len);
+ break;
+
+ default:
+ /* ����ģʽ�µķ�IPЭ��, ����ʹ��ϵͳ·�ɷ���, ����ʹ��raw_eth_fdͨ��ָ���������� */
+ ether_type = net_layer_to_ethernet_protocol(low_layer_type);
+ ret = packet_io_send_by_manual_conf(send_handle, datalen, dir, ether_type);
+ break;
+ }
+ }
+ }
+ else
+ {
+ ret = dl_io_fun_list.dl_io_low_level_send(send_handle->low_level_send_handle,
+ (UINT8 *)send_handle->send_buf,
+ datalen,
+ low_layer_type,
+ dir,
+ thread_num);
+ }
+
+ return ret;
+}
+
+/*
+ send_type:��������, RST, ��־, �ش����ݵ�;
+ low_layer_type:��MAC��֮��, ��ײ�Э������, ��IPv4, ipv6, VLAN��.
+ datalen :�ϲ�APP�ܳ�, ������MAC���14�ֽ�.
+*/
+int packet_io_send(MESA_send_handle *send_handle,int datalen,int send_type,
+ int low_layer_type, int dir,int thread_num,
+ char *feedback_buf, int *feedback_buf_len)
+{
+ int ret = -1;
+
+ switch(send_type){
+ case SEND_TYPE_LINK_INJECT:
+ ret = packet_io_send_fake_pkt(send_handle, datalen, send_type, low_layer_type,
+ dir, thread_num, feedback_buf, feedback_buf_len);
+ break;
+
+ case SEND_TYPE_LOG:
+ /* to do */
+ ret = -1;
+ break;
+
+ case SEND_TYPE_REDIRECT:
+ /* to do, ˮ�ԭʼ����ת�� */
+ ret = -1;
+ break;
+
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+
+
+send_raw_pkt_info_t *get_raw_pkt_conf_by_id(unsigned int target_id)
+{
+ int i;
+
+ for(i = 0; i < G_SND_RAW_PKT_INFO_NUM; i++){
+ if(target_id == G_SND_RAW_PKT_INFO[i].target_id){
+ return &(G_SND_RAW_PKT_INFO[i]);
+ }
+ }
+
+ //printf("Send raw pkt error! Not found target_id:%u\n", target_id);
+
+ return NULL;
+}
+
+int parse_send_gdev_ip_conf(const char *profile_path)
+{
+ FILE *fp;
+ char conf_buf[1024] = "";
+ int dev_id = 0;
+ char ip_addr[32] = "";
+ int ret = 0;
+ fp = fopen(profile_path, "r");
+ if(NULL == fp){
+ printf("open %s error!\n", profile_path);
+ return -1;
+ }
+
+ memset(g_send_gdev_ip_table, 0, sizeof(g_send_gdev_ip_table));
+ G_SND_GDEV_INFO_NUM = 0;
+
+ while(fgets(conf_buf, 1024, fp)){
+ if('#' == conf_buf[0] || ' ' == conf_buf[0] || '\r' == conf_buf[0] || '\n' == conf_buf[0]){
+ continue;
+ }
+
+ //del_last_rn(conf_buf, 1024);
+
+ ret = sscanf(conf_buf, "%d\t%s", &dev_id, ip_addr);
+
+ if(ret != 2 || dev_id >= 64 || strlen(ip_addr) >= 32)
+ {
+ printf("read %s error, line:%s!\n", profile_path, conf_buf);
+ G_SND_GDEV_INFO_NUM = 0;
+ break;
+ }
+
+ memcpy(g_send_gdev_ip_table[dev_id], ip_addr, strlen(ip_addr));
+
+ G_SND_GDEV_INFO_NUM++;
+ memset(conf_buf, 0, sizeof(conf_buf));
+ }
+ fclose(fp);
+ return 0;
+}
+
+int parse_send_route_conf(const char *profile_path)
+{
+ FILE *fp;
+ char conf_buf[1024] = "";
+ //const char *delim = "\t ";
+ int dev_id = 0, link_id = 0;
+ char mac_addr[18] = "";
+ int ret = 0;
+ fp = fopen(profile_path, "r");
+ if(NULL == fp){
+ printf("open %s error!\n", profile_path);
+ return -1;
+ }
+
+ memset(g_send_gateway_mac_table, 0, sizeof(g_send_gateway_mac_table));
+ G_SND_ROUTE_INFO_NUM = 0;
+
+ while(fgets(conf_buf, 1024, fp)){
+ if('#' == conf_buf[0] || ' ' == conf_buf[0] || '\r' == conf_buf[0] || '\n' == conf_buf[0]){
+ continue;
+ }
+
+ //del_last_rn(conf_buf, 1024);
+
+ ret = sscanf(conf_buf, "%d\t%d\t%s", &dev_id, &link_id, mac_addr);
+
+ if(ret != 3 || dev_id >= 64 || link_id >= 16 || strlen(mac_addr) >= 18)
+ {
+ printf("read %s error, line:%s!\n", profile_path, conf_buf);
+ G_SND_ROUTE_INFO_NUM = 0;
+ break;
+ }
+
+ memcpy(g_send_gateway_mac_table[dev_id][link_id], mac_addr, strlen(mac_addr));
+
+ G_SND_ROUTE_INFO_NUM++;
+ memset(conf_buf, 0, sizeof(conf_buf));
+ }
+ fclose(fp);
+ return 0;
+}
+
+static int parse_send_raw_pkt_conf(void)
+{
+ FILE *fp;
+ char conf_buf[1024];
+ const char *delim = "\t ";
+ char *saveptr;
+ char *section;
+
+ fp = fopen("conf/send_raw_pkt.conf", "r");
+ if(NULL == fp){
+ printf("open %s error!\n", "send_raw_pkt.conf");
+ return -1;
+ }
+
+ while(fgets(conf_buf, 1024, fp)){
+ if('#' == conf_buf[0] || ' ' == conf_buf[0] || '\r' == conf_buf[0] || '\n' == conf_buf[0]){
+ continue;
+ }
+
+ del_last_rn(conf_buf, 1024);
+
+ /* target_id */
+ section = strtok_r(conf_buf, delim, &saveptr);
+ if(NULL == section){
+ return -1;
+ }
+ G_SND_RAW_PKT_INFO[G_SND_RAW_PKT_INFO_NUM].target_id = strtoul(section, NULL, 10);
+
+ /* PAG args, net_card name */
+ section = strtok_r(NULL, delim, &saveptr);
+ if(NULL == section){
+ return -1;
+ }
+ memcpy(G_SND_RAW_PKT_INFO[G_SND_RAW_PKT_INFO_NUM].send_args[CAP_MODEL_PAG].dev_name, section, 128);
+
+ /* pcap args, device name */
+ section = strtok_r(NULL, delim, &saveptr);
+ if(NULL == section){
+ return -1;
+ }
+ memcpy(G_SND_RAW_PKT_INFO[G_SND_RAW_PKT_INFO_NUM].send_args[CAP_MODEL_PCAP_ONLINE].dev_name, section, 128);
+
+ /* PFRING args, net_card index */
+ section = strtok_r(NULL, delim, &saveptr);
+ if(NULL == section){
+ return -1;
+ }
+ memcpy(G_SND_RAW_PKT_INFO[G_SND_RAW_PKT_INFO_NUM].send_args[CAP_MODEL_PFRING].dev_name, section, 128);
+
+ /* DPDK args, port number */
+ section = strtok_r(NULL, delim, &saveptr);
+ if(NULL == section){
+ return -1;
+ }
+ G_SND_RAW_PKT_INFO[G_SND_RAW_PKT_INFO_NUM].send_args[CAP_MODEL_DPDK].port_id = strtoul(section, NULL, 10);
+
+ /* TODO 1, PPF args, port number */
+ section = strtok_r(NULL, delim, &saveptr);
+
+ /* TODO 1, PPF args, port number */
+ section = strtok_r(NULL, delim, &saveptr);
+
+ /* TODO 1, npacket args, port number */
+ section = strtok_r(NULL, delim, &saveptr);
+
+ /* TODO 1, qnf args, port number */
+ section = strtok_r(NULL, delim, &saveptr);
+
+ /* TODO 1, n95 args, port number */
+ section = strtok_r(NULL, delim, &saveptr);
+
+ while(strtok_r(NULL, delim, &saveptr)); /* clear line buf */
+
+ G_SND_RAW_PKT_INFO_NUM++;
+ }
+
+ fclose(fp);
+
+ return 0;
+}
+
+int packet_io_send_raw(int thread_num, char *data, int datalen,unsigned int target_id)
+{
+ MESA_send_handle *snd_handle;
+ send_raw_pkt_info_t *send_info;
+ int ret;
+
+ snd_handle = packet_io_get_send_handle(thread_num);
+ if(NULL == snd_handle){
+ return -1;
+ }
+
+ send_info = get_raw_pkt_conf_by_id(target_id);
+ if(NULL == send_info){
+ return -1;
+ }
+
+ ret = dl_io_fun_list.dl_io_raw_pkt_send(snd_handle->low_level_send_handle,
+ (unsigned char *)data,
+ datalen,
+ &(send_info->send_args[g_packet_io_cap_mode]),
+ thread_num);
+ return ret;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
diff --git a/packet_io/packet_io_status.cpp b/packet_io/packet_io_status.cpp
index faaba91..0c3218e 100644
--- a/packet_io/packet_io_status.cpp
+++ b/packet_io/packet_io_status.cpp
@@ -341,7 +341,7 @@ void *time_event_thread(void *arg)
if(g_CurrentTime > last_log_time){
last_log_time = g_CurrentTime;
sysinfo_output();
- pkt_runtime_output();
+ //pkt_runtime_output();
}
usleep(1000);
diff --git a/rmake b/rmake
index 95cfbd3..142a6b5 100644
--- a/rmake
+++ b/rmake
@@ -1,3 +1,3 @@
#!/bin/bash
rm -rf ./build/
-make -f cmake-makefile debug
+make -f makefile-cmake $1
diff --git a/run/conf/main.conf b/run/conf/main.conf
index 932be02..52e7cc4 100644
--- a/run/conf/main.conf
+++ b/run/conf/main.conf
@@ -24,9 +24,9 @@ kill_tcp_with_gdev=0
signal_take_over_switch=0
-timestamp_record=0
+timestamp_record=1
#timedelay_threshold unit: CPU CYCLE
-timedelay_threshold=9000000
+timedelay_threshold=100000
analyse_tcp_option=0
diff --git a/run/platform_lib/packet_io_pcap.so b/run/platform_lib/packet_io_pcap.so
index 227d21e..8979316 100644
--- a/run/platform_lib/packet_io_pcap.so
+++ b/run/platform_lib/packet_io_pcap.so
Binary files differ
diff --git a/run/plug/business/conflist_business.inf b/run/plug/business/conflist_business.inf
index cb360b5..f290cd3 100644
--- a/run/plug/business/conflist_business.inf
+++ b/run/plug/business/conflist_business.inf
@@ -6,4 +6,4 @@
#./plug/business/pptp_biz_sample/pptp_biz_sample.inf
#./plug/business/terminal_tag/terminal_tag.inf
#./plug/business/g_device_plug/g_device_plug.inf
-./plug/business/ntc_ip_comm/ntc_ip_comm.inf
+#./plug/business/ntc_ip_comm/ntc_ip_comm.inf
diff --git a/run/plug/business/g_device_plug/g_device_plug.so b/run/plug/business/g_device_plug/g_device_plug.so
index 01d4b4a..82d1f32 100644
--- a/run/plug/business/g_device_plug/g_device_plug.so
+++ b/run/plug/business/g_device_plug/g_device_plug.so
Binary files differ
diff --git a/run/plug/business/test_app/test_app_sapp.so b/run/plug/business/test_app/test_app_sapp.so
index 39e57b5..a3f617a 100644
--- a/run/plug/business/test_app/test_app_sapp.so
+++ b/run/plug/business/test_app/test_app_sapp.so
Binary files differ
diff --git a/run/plug/business/test_app/trace_delay.so b/run/plug/business/test_app/trace_delay.so
index 104b25d..b3d56c7 100644
--- a/run/plug/business/test_app/trace_delay.so
+++ b/run/plug/business/test_app/trace_delay.so
Binary files differ
diff --git a/run/plug/protocol/isakmp_protocol_plug/isakmp_protocol_plug.so b/run/plug/protocol/isakmp_protocol_plug/isakmp_protocol_plug.so
index 0b17952..6017a99 100644
--- a/run/plug/protocol/isakmp_protocol_plug/isakmp_protocol_plug.so
+++ b/run/plug/protocol/isakmp_protocol_plug/isakmp_protocol_plug.so
Binary files differ
diff --git a/run/plug/protocol/l2tp_protocol_plug/l2tp_protocol_plug.so b/run/plug/protocol/l2tp_protocol_plug/l2tp_protocol_plug.so
index 04af272..cff3860 100644
--- a/run/plug/protocol/l2tp_protocol_plug/l2tp_protocol_plug.so
+++ b/run/plug/protocol/l2tp_protocol_plug/l2tp_protocol_plug.so
Binary files differ
diff --git a/run/plug/protocol/pptp_protocol_plug/pptp_protocol_plug.so b/run/plug/protocol/pptp_protocol_plug/pptp_protocol_plug.so
index 476cd9a..9d057fb 100644
--- a/run/plug/protocol/pptp_protocol_plug/pptp_protocol_plug.so
+++ b/run/plug/protocol/pptp_protocol_plug/pptp_protocol_plug.so
Binary files differ
diff --git a/support/avl_tree/avltree.c b/support/avl_tree/avltree.c
index e453a29..7d77947 100644
--- a/support/avl_tree/avltree.c
+++ b/support/avl_tree/avltree.c
@@ -1,704 +1,704 @@
-/*
-Copyright (C) 2014-present Jung-Sang Ahn <[email protected]>
-All rights reserved.
-
-Last modification: Jan 20, 2017
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-*/
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef INLINE
- #ifdef __APPLE__
- #define INLINE extern inline
- #elif __linux__
- #define INLINE __inline
- #else
- #define INLINE
- #endif
-#endif
-
-#include "avltree.h"
-
-#define max(a,b) (((a) > (b)) ? (a) : (b))
-
-INLINE int _abs(int n) {
- int mask = n >> ((sizeof(int)*8) -1);
- return (mask + n)^mask;
-}
-
-INLINE void avl_set_parent(struct avl_node *node, struct avl_node *parent)
-{
- node->parent = (struct avl_node *)(
- (uint64_t)parent | ((uint64_t)node->parent & 0x3));
-}
-
-#ifdef __AVL_DEBUG
-#include <stdio.h>
-#include <assert.h>
-#include "avltree_debug.h"
-#else
-#define __AVL_DEBUG_BF_CHECK(bf)
-#define __AVL_DEBUG_LL(p, c, pb, cb)
-#define __AVL_DEBUG_RR(p, c, pb, cb)
-#define __AVL_DEBUG_BAL_BEGIN(node, bf, height_diff)
-#define __AVL_DEBUG_BAL_END(node)
-#define __AVL_DEBUG_INSERT(node)
-#define __AVL_DEBUG_REMOVE(node)
-#define __AVL_DEBUG_DISPLAY(tree)
-#endif
-
-INLINE void avl_set_bf(struct avl_node *node, int bf)
-{
- __AVL_DEBUG_BF_CHECK(bf);
-
-#ifdef _AVL_SEPARATE_PARENT_BF
- node->bf = bf;
-#else
- node->parent = (struct avl_node *)(
- (uint64_t)avl_parent(node) | (uint64_t)(bf+1));
-#endif
-}
-
-INLINE struct avl_node* _rotate_LL(struct avl_node *parent,
- int parent_bf,
- int *child_bf,
- int *height_delta)
-// MUST ensure that parent_bf <= 0
-{
- int p_right, c_left, c_right;
- struct avl_node *child = parent->left;
-
- __AVL_DEBUG_LL(parent, child, parent_bf, *child_bf);
-
- c_left = (child->left)?(1):(0);
- c_right = (child->right)?(1):(0);
- if (*child_bf < 0) {
- // child->left > child->right
- c_left = c_right - (*child_bf);
- p_right = c_left + 1 + parent_bf;
- if (height_delta)
- *height_delta = max(c_left, max(c_right, p_right)+1) - (c_left + 1);
-
- } else {
- // child->left <= child->right
- c_right = c_left + (*child_bf);
- p_right = c_right + 1 + parent_bf;
- if (height_delta)
- *height_delta = max(c_left, max(c_right, p_right)+1) - (c_right + 1);
- }
- *child_bf = (max(c_right, p_right) + 1) - c_left;
- avl_set_bf(parent, p_right - c_right);
-
- parent->left = child->right;
- if (child->right)
- avl_set_parent(child->right, parent);
- child->right = parent;
- avl_set_parent(child, avl_parent(parent));
- avl_set_parent(parent, child);
-
- return child;
-}
-
-INLINE struct avl_node* _rotate_RR(struct avl_node *parent,
- int parent_bf,
- int *child_bf,
- int *height_delta)
-// MUST ensure that parent_bf >= 0
-{
- int p_left, c_left, c_right;
- struct avl_node *child = parent->right;
-
- __AVL_DEBUG_RR(parent, child, parent_bf, *child_bf);
-
- c_left = (child->left)?(1):(0);
- c_right = (child->right)?(1):(0);
- if (*child_bf < 0) {
- // child->left > child->right
- c_left = c_right - (*child_bf);
- p_left = c_left + 1 - parent_bf;
- if (height_delta)
- *height_delta = max(c_right, max(c_left, p_left)+1) - (c_left + 1);
-
- } else {
- // child->left <= child->right
- c_right = c_left + (*child_bf);
- p_left = c_right + 1 - parent_bf;
- if (height_delta)
- *height_delta = max(c_right, max(c_left, p_left)+1) - (c_right + 1);
-
- }
- *child_bf = c_right - (max(c_left, p_left) + 1);
- avl_set_bf(parent, c_left - p_left);
-
- parent->right = child->left;
- if (child->left)
- avl_set_parent(child->left, parent);
- child->left = parent;
- avl_set_parent(child, avl_parent(parent));
- avl_set_parent(parent, child);
-
- return child;
-}
-
-INLINE struct avl_node* _rotate_LR(struct avl_node *parent, int parent_bf)
-{
- int child_bf, height_delta = 0;
- struct avl_node *child = parent->left;
- struct avl_node *ret;
-
- if (child->right) {
- child_bf = avl_bf(child->right);
- parent->left = _rotate_RR(child, avl_bf(child), &child_bf, &height_delta);
- } else {
- child_bf = avl_bf(child);
- }
-
- ret = _rotate_LL(parent, parent_bf-height_delta, &child_bf, NULL);
- avl_set_bf(ret, child_bf);
- return ret;
-}
-
-INLINE struct avl_node* _rotate_RL(struct avl_node *parent, int parent_bf)
-{
- int child_bf, height_delta = 0;
- struct avl_node *child = parent->right;
- struct avl_node *ret;
-
- if (child->left) {
- child_bf = avl_bf(child->left);
- parent->right = _rotate_LL(child, avl_bf(child), &child_bf, &height_delta);
- } else {
- child_bf = avl_bf(child);
- }
-
- ret = _rotate_RR(parent, parent_bf+height_delta, &child_bf, NULL);
- avl_set_bf(ret, child_bf);
- return ret;
-}
-
-#define _get_balance(node) ((node)?(avl_bf(node)):(0))
-
-static struct avl_node* _balance_tree(struct avl_node *node, int bf)
-{
- int child_bf;
- int height_diff= _get_balance(node) + bf;
-
- if (node) {
- __AVL_DEBUG_BAL_BEGIN(node, bf, height_diff);
-
- if(height_diff < -1 && node->left) {
- // balance left sub tree
- if(_get_balance(node->left) <= 0) {
- child_bf = avl_bf(node->left);
- node = _rotate_LL(node, height_diff, &child_bf, NULL);
- avl_set_bf(node, child_bf);
- } else {
- node = _rotate_LR(node, height_diff);
- }
- } else if(height_diff > 1 && node->right) {
- // balance right sub tree
- if(_get_balance(node->right) >= 0) {
- child_bf = avl_bf(node->right);
- node = _rotate_RR(node, height_diff, &child_bf, NULL);
- avl_set_bf(node, child_bf);
- } else {
- node = _rotate_RL(node, height_diff);
- }
- } else {
- avl_set_bf(node, avl_bf(node) + bf);
- }
-
- __AVL_DEBUG_BAL_END(node);
- }
-
- return node;
-}
-
-struct avl_node* avl_first(struct avl_tree *tree)
-{
- struct avl_node *p = NULL;
- struct avl_node *node = tree->root;
-
- while(node) {
- p = node;
- node = node->left;
- }
- return p;
-}
-
-struct avl_node* avl_last(struct avl_tree *tree)
-{
- struct avl_node *p = NULL;
- struct avl_node *node = tree->root;
-
- while(node) {
- p = node;
- node = node->right;
- }
- return p;
-}
-
-struct avl_node* avl_next(struct avl_node *node)
-{
- if (node == NULL) return NULL;
-
-#ifdef _AVL_NEXT_POINTER
- return node->next;
-#else
-
- struct avl_node *p;
-
- // smallest value of right subtree
- if (node->right) {
- p = node;
- node = node->right;
- while (node) {
- p = node;
- node = node->left;
- }
- return p;
- }
-
- // node does not have right child
- if (avl_parent(node)) {
- // find first parent that has right child
- p = node;
- node = avl_parent(node);
- while(node) {
- if (node->left == p) {
- return node;
- }
- p = node;
- node = avl_parent(node);
- }
- }
-#endif
- return NULL;
-}
-
-struct avl_node* avl_prev(struct avl_node *node)
-{
- if (node == NULL) return NULL;
-
-#ifdef _AVL_NEXT_POINTER
- return node->prev;
-#else
-
- struct avl_node *p;
-
- // largest value of left subtree
- if (node->left) {
- p = node;
- node = node->left;
- while (node) {
- p = node;
- node = node->right;
- }
- return p;
- }
-
- // node does not have left child
- if (avl_parent(node)) {
- // find first parent that has left child
- p = node;
- node = avl_parent(node);
- while(node) {
- if (node->right == p) {
- return node;
- }
- p = node;
- node = avl_parent(node);
- }
- }
-#endif
- return NULL;
-}
-
-struct avl_node* avl_search(struct avl_tree *tree,
- struct avl_node *node,
- avl_cmp_func *func)
-// exact match
-{
- struct avl_node *p = tree->root;
- int cmp;
-
- while(p)
- {
- cmp = func(p, node, tree->aux);
- if (cmp > 0) {
- p = p->left;
- }else if (cmp < 0){
- p = p->right;
- }else {
- // search success
- return p;
- }
- }
- // search fail
- return NULL;
-}
-
-struct avl_node* avl_search_greater(struct avl_tree *tree,
- struct avl_node *node,
- avl_cmp_func *func)
-// if an exact match does not exist,
-// return smallest node greater than NODE
-{
- struct avl_node *p = tree->root;
- struct avl_node *pp = NULL;
- int cmp;
-
- while(p)
- {
- cmp = func(p, node, tree->aux);
- pp = p;
-
- if (cmp > 0) {
- p = p->left;
- }else if (cmp < 0){
- p = p->right;
- }else {
- // search success
- return p;
- }
- }
-
- if (!pp) {
- return pp;
- }
-
- cmp = func(pp, node, tree->aux);
- if (cmp > 0) {
- return pp;
- }else{
- return avl_next(pp);
- }
-}
-
-struct avl_node* avl_search_smaller(struct avl_tree *tree,
- struct avl_node *node,
- avl_cmp_func *func)
-// if an exact match does not exist,
-// return greatest node smaller than NODE
-{
- struct avl_node *p = tree->root;
- struct avl_node *pp = NULL;
- int cmp;
-
- while(p)
- {
- cmp = func(p, node, tree->aux);
- pp = p;
-
- if (cmp > 0) {
- p = p->left;
- }else if (cmp < 0){
- p = p->right;
- }else {
- // search success
- return p;
- }
- }
-
- if (!pp) {
- return pp;
- }
-
- cmp = func(pp, node, tree->aux);
- if (cmp < 0) {
- return pp;
- }else{
- return avl_prev(pp);
- }
-}
-
-void avl_init(struct avl_tree *tree, void *aux)
-{
- tree->root = NULL;
- tree->aux = aux;
-}
-
-void avl_set_aux(struct avl_tree *tree, void *aux)
-{
- tree->aux = aux;
-}
-
-struct avl_node* avl_insert(struct avl_tree *tree,
- struct avl_node *node,
- avl_cmp_func *func)
-{
- __AVL_DEBUG_INSERT(node);
-
- struct avl_node *node_original = node;
- struct avl_node *p=NULL,*cur;
- int cmp, bf, bf_old;
-
- cur = tree->root;
- while(cur)
- {
- cmp = func(cur, node, tree->aux);
- p = cur;
-
- if(cmp > 0) {
- cur = cur->left;
- }else if (cmp < 0){
- cur = cur->right;
- }else {
- // duplicated key -> return
- //return cur;
- return NULL; /* modify by lijia, ʹ��NULL�������ʧ�ܵ���� */
- }
- }
-
- avl_set_parent(node, p);
- avl_set_bf(node, 0);
- node->left = node->right = NULL;
-#ifdef _AVL_NEXT_POINTER
- node->prev = node->next = NULL;
-#endif
-
- // P is parent node of CUR
- if(p) {
- if(func(p, node, tree->aux) > 0) {
- p->left = node;
-#ifdef _AVL_NEXT_POINTER
- node->next = p;
- node->prev = p->prev;
- if (p->prev) p->prev->next = node;
- p->prev = node;
-#endif
-
- }else {
- p->right = node;
-#ifdef _AVL_NEXT_POINTER
- node->prev = p;
- node->next = p->next;
- if (p->next) p->next->prev = node;
- p->next = node;
-#endif
- }
-
- } else {
- // no parent .. make NODE as root
- tree->root = node;
- }
-
- // recursive balancing process .. scan from leaf to root
- bf = 0;
- while(node) {
- p = avl_parent(node);
-
- if (p) {
- // if parent exists
- bf_old = avl_bf(node);
-
- if (p->right == node) {
- node = _balance_tree(node, bf);
- p->right = node;
- }else {
- node = _balance_tree(node, bf);
- p->left = node;
- }
-
- // calculate balance facter BF for parent
- if (node->left == NULL && node->right == NULL) {
- // leaf node
- if (p->left == node) bf = -1;
- else bf = 1;
- } else {
- // index ndoe
- bf = 0;
- if (_abs(bf_old) < _abs(avl_bf(node))) {
- // if ABS of balance factor increases
- // cascade to parent
- if (p->left == node) bf = -1;
- else bf = 1;
- }
- }
-
- } else if(node == tree->root){
- tree->root = _balance_tree(tree->root, bf);
- break;
- }
- if (bf == 0) break;
-
- node = p;
- }
-
- __AVL_DEBUG_DISPLAY(tree);
-
- /* add by lijia, ����Ԫ�ؼ��� */
- long num = (long )tree->aux;
- num++;
- tree->aux = (void *)num;
-
- return node_original;
-}
-
-void avl_remove(struct avl_tree *tree,
- struct avl_node *node)
-{
- __AVL_DEBUG_REMOVE(node);
-
- // not found
- if (node == NULL) return;
-
- struct avl_tree right_subtree;
- struct avl_node *p=NULL,*cur, *next=NULL;
- int bf = 0, bf_old;
-
- if((NULL == node->parent) && (NULL == node->left) && (NULL == node->right)){
- return;
- }
-
-#ifdef _AVL_NEXT_POINTER
- if (node->prev) node->prev->next = node->next;
- if (node->next) node->next->prev = node->prev;
-#endif
-
- // find smallest node in right sub-tree
- right_subtree.root = node->right;
- next = avl_first(&right_subtree);
-
- if (next) {
- // 1. NEXT exists
- if (avl_parent(next)) {
- if (avl_parent(next) != node) {
- // NODE is not NEXT's direct parent
- // MUST ensure NEXT should be *left child* of its parent
- // MUST ensure NEXT doesn't have right child
- avl_parent(next)->left = next->right;
- if (next->right)
- avl_set_parent(next->right, avl_parent(next));
- }
- }
- if (avl_parent(node)) {
- // replace NODE by NEXT
- if (avl_parent(node)->left == node) {
- avl_parent(node)->left = next;
- } else {
- avl_parent(node)->right = next;
- }
- }
-
- // re-link pointers
- if (node->right != next) {
- next->right = node->right;
- if (node->right) avl_set_parent(node->right, next);
- cur = avl_parent(next);
- bf = 1;
- }else{
- cur = next;
- bf = -1;
- }
-
- next->left = node->left;
- if (node->left) avl_set_parent(node->left, next);
- avl_set_parent(next, avl_parent(node));
-
- // inherit NODE's balance factor
- avl_set_bf(next, avl_bf(node));
-
- } else {
- // 2. NEXT == NULL (only when there's no right sub-tree)
- p = avl_parent(node);
- if (p) {
- if (p->left == node) {
- p->left = node->left;
- bf = 1;
- } else {
- p->right = node->left;
- bf = -1;
- }
- }
- if (node->left)
- avl_set_parent(node->left, p);
-
- cur = avl_parent(node);
- }
-
- // reset root
- if (tree->root == node) {
- tree->root = next;
- if (next == NULL) {
- if (node->left) tree->root = node->left;
- }
- }
-
- // recursive balancing process .. scan from CUR to root
- while(cur) {
- p = avl_parent(cur);
- if (p) {
- // if parent exists
- bf_old = avl_bf(cur);
-
- if (p->right == cur) {
- cur = _balance_tree(cur, bf);
- p->right = cur;
- }else {
- cur = _balance_tree(cur, bf);
- p->left = cur;
- }
-
- // calculate balance facter BF for parent
- if (cur->left == NULL && cur->right == NULL) {
- // leaf node
- if (p->left == cur) bf = 1;
- else bf = -1;
- } else {
- // index ndoe
- bf = 0;
- if (_abs(bf_old) > _abs(avl_bf(cur))) {
- // if ABS of balance factor decreases
- // cascade to parent
- if (p->left == cur) bf = 1;
- else bf = -1;
- }
- }
-
- } else if(cur == tree->root){
- tree->root = _balance_tree(tree->root, bf);
- break;
- }
- if (bf == 0) break;
-
- cur = p;
- }
-
- /* add by lijia, ����Ԫ�ؼ��� */
- long num = (long )tree->aux;
- num--;
- tree->aux = (void *)num;
-
- node->left = NULL;
- node->right = NULL;
- node->parent = NULL;
-
- __AVL_DEBUG_DISPLAY(tree);
-}
-
-#ifdef __cplusplus
-}
-#endif
+/*
+Copyright (C) 2014-present Jung-Sang Ahn <[email protected]>
+All rights reserved.
+
+Last modification: Jan 20, 2017
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef INLINE
+ #ifdef __APPLE__
+ #define INLINE extern inline
+ #elif __linux__
+ #define INLINE __inline
+ #else
+ #define INLINE
+ #endif
+#endif
+
+#include "avltree.h"
+
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+
+int _abs(int n) {
+ int mask = n >> ((sizeof(int)*8) -1);
+ return (mask + n)^mask;
+}
+
+void avl_set_parent(struct avl_node *node, struct avl_node *parent)
+{
+ node->parent = (struct avl_node *)(
+ (uint64_t)parent | ((uint64_t)node->parent & 0x3));
+}
+
+#ifdef __AVL_DEBUG
+#include <stdio.h>
+#include <assert.h>
+#include "avltree_debug.h"
+#else
+#define __AVL_DEBUG_BF_CHECK(bf)
+#define __AVL_DEBUG_LL(p, c, pb, cb)
+#define __AVL_DEBUG_RR(p, c, pb, cb)
+#define __AVL_DEBUG_BAL_BEGIN(node, bf, height_diff)
+#define __AVL_DEBUG_BAL_END(node)
+#define __AVL_DEBUG_INSERT(node)
+#define __AVL_DEBUG_REMOVE(node)
+#define __AVL_DEBUG_DISPLAY(tree)
+#endif
+
+void avl_set_bf(struct avl_node *node, int bf)
+{
+ __AVL_DEBUG_BF_CHECK(bf);
+
+#ifdef _AVL_SEPARATE_PARENT_BF
+ node->bf = bf;
+#else
+ node->parent = (struct avl_node *)(
+ (uint64_t)avl_parent(node) | (uint64_t)(bf+1));
+#endif
+}
+
+struct avl_node* _rotate_LL(struct avl_node *parent,
+ int parent_bf,
+ int *child_bf,
+ int *height_delta)
+// MUST ensure that parent_bf <= 0
+{
+ int p_right, c_left, c_right;
+ struct avl_node *child = parent->left;
+
+ __AVL_DEBUG_LL(parent, child, parent_bf, *child_bf);
+
+ c_left = (child->left)?(1):(0);
+ c_right = (child->right)?(1):(0);
+ if (*child_bf < 0) {
+ // child->left > child->right
+ c_left = c_right - (*child_bf);
+ p_right = c_left + 1 + parent_bf;
+ if (height_delta)
+ *height_delta = max(c_left, max(c_right, p_right)+1) - (c_left + 1);
+
+ } else {
+ // child->left <= child->right
+ c_right = c_left + (*child_bf);
+ p_right = c_right + 1 + parent_bf;
+ if (height_delta)
+ *height_delta = max(c_left, max(c_right, p_right)+1) - (c_right + 1);
+ }
+ *child_bf = (max(c_right, p_right) + 1) - c_left;
+ avl_set_bf(parent, p_right - c_right);
+
+ parent->left = child->right;
+ if (child->right)
+ avl_set_parent(child->right, parent);
+ child->right = parent;
+ avl_set_parent(child, avl_parent(parent));
+ avl_set_parent(parent, child);
+
+ return child;
+}
+
+struct avl_node* _rotate_RR(struct avl_node *parent,
+ int parent_bf,
+ int *child_bf,
+ int *height_delta)
+// MUST ensure that parent_bf >= 0
+{
+ int p_left, c_left, c_right;
+ struct avl_node *child = parent->right;
+
+ __AVL_DEBUG_RR(parent, child, parent_bf, *child_bf);
+
+ c_left = (child->left)?(1):(0);
+ c_right = (child->right)?(1):(0);
+ if (*child_bf < 0) {
+ // child->left > child->right
+ c_left = c_right - (*child_bf);
+ p_left = c_left + 1 - parent_bf;
+ if (height_delta)
+ *height_delta = max(c_right, max(c_left, p_left)+1) - (c_left + 1);
+
+ } else {
+ // child->left <= child->right
+ c_right = c_left + (*child_bf);
+ p_left = c_right + 1 - parent_bf;
+ if (height_delta)
+ *height_delta = max(c_right, max(c_left, p_left)+1) - (c_right + 1);
+
+ }
+ *child_bf = c_right - (max(c_left, p_left) + 1);
+ avl_set_bf(parent, c_left - p_left);
+
+ parent->right = child->left;
+ if (child->left)
+ avl_set_parent(child->left, parent);
+ child->left = parent;
+ avl_set_parent(child, avl_parent(parent));
+ avl_set_parent(parent, child);
+
+ return child;
+}
+
+struct avl_node* _rotate_LR(struct avl_node *parent, int parent_bf)
+{
+ int child_bf, height_delta = 0;
+ struct avl_node *child = parent->left;
+ struct avl_node *ret;
+
+ if (child->right) {
+ child_bf = avl_bf(child->right);
+ parent->left = _rotate_RR(child, avl_bf(child), &child_bf, &height_delta);
+ } else {
+ child_bf = avl_bf(child);
+ }
+
+ ret = _rotate_LL(parent, parent_bf-height_delta, &child_bf, NULL);
+ avl_set_bf(ret, child_bf);
+ return ret;
+}
+
+struct avl_node* _rotate_RL(struct avl_node *parent, int parent_bf)
+{
+ int child_bf, height_delta = 0;
+ struct avl_node *child = parent->right;
+ struct avl_node *ret;
+
+ if (child->left) {
+ child_bf = avl_bf(child->left);
+ parent->right = _rotate_LL(child, avl_bf(child), &child_bf, &height_delta);
+ } else {
+ child_bf = avl_bf(child);
+ }
+
+ ret = _rotate_RR(parent, parent_bf+height_delta, &child_bf, NULL);
+ avl_set_bf(ret, child_bf);
+ return ret;
+}
+
+#define _get_balance(node) ((node)?(avl_bf(node)):(0))
+
+static struct avl_node* _balance_tree(struct avl_node *node, int bf)
+{
+ int child_bf;
+ int height_diff= _get_balance(node) + bf;
+
+ if (node) {
+ __AVL_DEBUG_BAL_BEGIN(node, bf, height_diff);
+
+ if(height_diff < -1 && node->left) {
+ // balance left sub tree
+ if(_get_balance(node->left) <= 0) {
+ child_bf = avl_bf(node->left);
+ node = _rotate_LL(node, height_diff, &child_bf, NULL);
+ avl_set_bf(node, child_bf);
+ } else {
+ node = _rotate_LR(node, height_diff);
+ }
+ } else if(height_diff > 1 && node->right) {
+ // balance right sub tree
+ if(_get_balance(node->right) >= 0) {
+ child_bf = avl_bf(node->right);
+ node = _rotate_RR(node, height_diff, &child_bf, NULL);
+ avl_set_bf(node, child_bf);
+ } else {
+ node = _rotate_RL(node, height_diff);
+ }
+ } else {
+ avl_set_bf(node, avl_bf(node) + bf);
+ }
+
+ __AVL_DEBUG_BAL_END(node);
+ }
+
+ return node;
+}
+
+struct avl_node* avl_first(struct avl_tree *tree)
+{
+ struct avl_node *p = NULL;
+ struct avl_node *node = tree->root;
+
+ while(node) {
+ p = node;
+ node = node->left;
+ }
+ return p;
+}
+
+struct avl_node* avl_last(struct avl_tree *tree)
+{
+ struct avl_node *p = NULL;
+ struct avl_node *node = tree->root;
+
+ while(node) {
+ p = node;
+ node = node->right;
+ }
+ return p;
+}
+
+struct avl_node* avl_next(struct avl_node *node)
+{
+ if (node == NULL) return NULL;
+
+#ifdef _AVL_NEXT_POINTER
+ return node->next;
+#else
+
+ struct avl_node *p;
+
+ // smallest value of right subtree
+ if (node->right) {
+ p = node;
+ node = node->right;
+ while (node) {
+ p = node;
+ node = node->left;
+ }
+ return p;
+ }
+
+ // node does not have right child
+ if (avl_parent(node)) {
+ // find first parent that has right child
+ p = node;
+ node = avl_parent(node);
+ while(node) {
+ if (node->left == p) {
+ return node;
+ }
+ p = node;
+ node = avl_parent(node);
+ }
+ }
+#endif
+ return NULL;
+}
+
+struct avl_node* avl_prev(struct avl_node *node)
+{
+ if (node == NULL) return NULL;
+
+#ifdef _AVL_NEXT_POINTER
+ return node->prev;
+#else
+
+ struct avl_node *p;
+
+ // largest value of left subtree
+ if (node->left) {
+ p = node;
+ node = node->left;
+ while (node) {
+ p = node;
+ node = node->right;
+ }
+ return p;
+ }
+
+ // node does not have left child
+ if (avl_parent(node)) {
+ // find first parent that has left child
+ p = node;
+ node = avl_parent(node);
+ while(node) {
+ if (node->right == p) {
+ return node;
+ }
+ p = node;
+ node = avl_parent(node);
+ }
+ }
+#endif
+ return NULL;
+}
+
+struct avl_node* avl_search(struct avl_tree *tree,
+ struct avl_node *node,
+ avl_cmp_func *func)
+// exact match
+{
+ struct avl_node *p = tree->root;
+ int cmp;
+
+ while(p)
+ {
+ cmp = func(p, node, tree->aux);
+ if (cmp > 0) {
+ p = p->left;
+ }else if (cmp < 0){
+ p = p->right;
+ }else {
+ // search success
+ return p;
+ }
+ }
+ // search fail
+ return NULL;
+}
+
+struct avl_node* avl_search_greater(struct avl_tree *tree,
+ struct avl_node *node,
+ avl_cmp_func *func)
+// if an exact match does not exist,
+// return smallest node greater than NODE
+{
+ struct avl_node *p = tree->root;
+ struct avl_node *pp = NULL;
+ int cmp;
+
+ while(p)
+ {
+ cmp = func(p, node, tree->aux);
+ pp = p;
+
+ if (cmp > 0) {
+ p = p->left;
+ }else if (cmp < 0){
+ p = p->right;
+ }else {
+ // search success
+ return p;
+ }
+ }
+
+ if (!pp) {
+ return pp;
+ }
+
+ cmp = func(pp, node, tree->aux);
+ if (cmp > 0) {
+ return pp;
+ }else{
+ return avl_next(pp);
+ }
+}
+
+struct avl_node* avl_search_smaller(struct avl_tree *tree,
+ struct avl_node *node,
+ avl_cmp_func *func)
+// if an exact match does not exist,
+// return greatest node smaller than NODE
+{
+ struct avl_node *p = tree->root;
+ struct avl_node *pp = NULL;
+ int cmp;
+
+ while(p)
+ {
+ cmp = func(p, node, tree->aux);
+ pp = p;
+
+ if (cmp > 0) {
+ p = p->left;
+ }else if (cmp < 0){
+ p = p->right;
+ }else {
+ // search success
+ return p;
+ }
+ }
+
+ if (!pp) {
+ return pp;
+ }
+
+ cmp = func(pp, node, tree->aux);
+ if (cmp < 0) {
+ return pp;
+ }else{
+ return avl_prev(pp);
+ }
+}
+
+void avl_init(struct avl_tree *tree, void *aux)
+{
+ tree->root = NULL;
+ tree->aux = aux;
+}
+
+void avl_set_aux(struct avl_tree *tree, void *aux)
+{
+ tree->aux = aux;
+}
+
+struct avl_node* avl_insert(struct avl_tree *tree,
+ struct avl_node *node,
+ avl_cmp_func *func)
+{
+ __AVL_DEBUG_INSERT(node);
+
+ struct avl_node *node_original = node;
+ struct avl_node *p=NULL,*cur;
+ int cmp, bf, bf_old;
+
+ cur = tree->root;
+ while(cur)
+ {
+ cmp = func(cur, node, tree->aux);
+ p = cur;
+
+ if(cmp > 0) {
+ cur = cur->left;
+ }else if (cmp < 0){
+ cur = cur->right;
+ }else {
+ // duplicated key -> return
+ //return cur;
+ return NULL; /* modify by lijia, ʹ��NULL�������ʧ�ܵ���� */
+ }
+ }
+
+ avl_set_parent(node, p);
+ avl_set_bf(node, 0);
+ node->left = node->right = NULL;
+#ifdef _AVL_NEXT_POINTER
+ node->prev = node->next = NULL;
+#endif
+
+ // P is parent node of CUR
+ if(p) {
+ if(func(p, node, tree->aux) > 0) {
+ p->left = node;
+#ifdef _AVL_NEXT_POINTER
+ node->next = p;
+ node->prev = p->prev;
+ if (p->prev) p->prev->next = node;
+ p->prev = node;
+#endif
+
+ }else {
+ p->right = node;
+#ifdef _AVL_NEXT_POINTER
+ node->prev = p;
+ node->next = p->next;
+ if (p->next) p->next->prev = node;
+ p->next = node;
+#endif
+ }
+
+ } else {
+ // no parent .. make NODE as root
+ tree->root = node;
+ }
+
+ // recursive balancing process .. scan from leaf to root
+ bf = 0;
+ while(node) {
+ p = avl_parent(node);
+
+ if (p) {
+ // if parent exists
+ bf_old = avl_bf(node);
+
+ if (p->right == node) {
+ node = _balance_tree(node, bf);
+ p->right = node;
+ }else {
+ node = _balance_tree(node, bf);
+ p->left = node;
+ }
+
+ // calculate balance facter BF for parent
+ if (node->left == NULL && node->right == NULL) {
+ // leaf node
+ if (p->left == node) bf = -1;
+ else bf = 1;
+ } else {
+ // index ndoe
+ bf = 0;
+ if (_abs(bf_old) < _abs(avl_bf(node))) {
+ // if ABS of balance factor increases
+ // cascade to parent
+ if (p->left == node) bf = -1;
+ else bf = 1;
+ }
+ }
+
+ } else if(node == tree->root){
+ tree->root = _balance_tree(tree->root, bf);
+ break;
+ }
+ if (bf == 0) break;
+
+ node = p;
+ }
+
+ __AVL_DEBUG_DISPLAY(tree);
+
+ /* add by lijia, ����Ԫ�ؼ��� */
+ long num = (long )tree->aux;
+ num++;
+ tree->aux = (void *)num;
+
+ return node_original;
+}
+
+void avl_remove(struct avl_tree *tree,
+ struct avl_node *node)
+{
+ __AVL_DEBUG_REMOVE(node);
+
+ // not found
+ if (node == NULL) return;
+
+ struct avl_tree right_subtree;
+ struct avl_node *p=NULL,*cur, *next=NULL;
+ int bf = 0, bf_old;
+
+ if((NULL == node->parent) && (NULL == node->left) && (NULL == node->right)){
+ return;
+ }
+
+#ifdef _AVL_NEXT_POINTER
+ if (node->prev) node->prev->next = node->next;
+ if (node->next) node->next->prev = node->prev;
+#endif
+
+ // find smallest node in right sub-tree
+ right_subtree.root = node->right;
+ next = avl_first(&right_subtree);
+
+ if (next) {
+ // 1. NEXT exists
+ if (avl_parent(next)) {
+ if (avl_parent(next) != node) {
+ // NODE is not NEXT's direct parent
+ // MUST ensure NEXT should be *left child* of its parent
+ // MUST ensure NEXT doesn't have right child
+ avl_parent(next)->left = next->right;
+ if (next->right)
+ avl_set_parent(next->right, avl_parent(next));
+ }
+ }
+ if (avl_parent(node)) {
+ // replace NODE by NEXT
+ if (avl_parent(node)->left == node) {
+ avl_parent(node)->left = next;
+ } else {
+ avl_parent(node)->right = next;
+ }
+ }
+
+ // re-link pointers
+ if (node->right != next) {
+ next->right = node->right;
+ if (node->right) avl_set_parent(node->right, next);
+ cur = avl_parent(next);
+ bf = 1;
+ }else{
+ cur = next;
+ bf = -1;
+ }
+
+ next->left = node->left;
+ if (node->left) avl_set_parent(node->left, next);
+ avl_set_parent(next, avl_parent(node));
+
+ // inherit NODE's balance factor
+ avl_set_bf(next, avl_bf(node));
+
+ } else {
+ // 2. NEXT == NULL (only when there's no right sub-tree)
+ p = avl_parent(node);
+ if (p) {
+ if (p->left == node) {
+ p->left = node->left;
+ bf = 1;
+ } else {
+ p->right = node->left;
+ bf = -1;
+ }
+ }
+ if (node->left)
+ avl_set_parent(node->left, p);
+
+ cur = avl_parent(node);
+ }
+
+ // reset root
+ if (tree->root == node) {
+ tree->root = next;
+ if (next == NULL) {
+ if (node->left) tree->root = node->left;
+ }
+ }
+
+ // recursive balancing process .. scan from CUR to root
+ while(cur) {
+ p = avl_parent(cur);
+ if (p) {
+ // if parent exists
+ bf_old = avl_bf(cur);
+
+ if (p->right == cur) {
+ cur = _balance_tree(cur, bf);
+ p->right = cur;
+ }else {
+ cur = _balance_tree(cur, bf);
+ p->left = cur;
+ }
+
+ // calculate balance facter BF for parent
+ if (cur->left == NULL && cur->right == NULL) {
+ // leaf node
+ if (p->left == cur) bf = 1;
+ else bf = -1;
+ } else {
+ // index ndoe
+ bf = 0;
+ if (_abs(bf_old) > _abs(avl_bf(cur))) {
+ // if ABS of balance factor decreases
+ // cascade to parent
+ if (p->left == cur) bf = 1;
+ else bf = -1;
+ }
+ }
+
+ } else if(cur == tree->root){
+ tree->root = _balance_tree(tree->root, bf);
+ break;
+ }
+ if (bf == 0) break;
+
+ cur = p;
+ }
+
+ /* add by lijia, ����Ԫ�ؼ��� */
+ long num = (long )tree->aux;
+ num--;
+ tree->aux = (void *)num;
+
+ node->left = NULL;
+ node->right = NULL;
+ node->parent = NULL;
+
+ __AVL_DEBUG_DISPLAY(tree);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/support/dictator2/src/CMakeLists.txt b/support/dictator2/src/CMakeLists.txt
index adc48dc..57959e0 100644
--- a/support/dictator2/src/CMakeLists.txt
+++ b/support/dictator2/src/CMakeLists.txt
@@ -8,7 +8,7 @@ include_directories(${MESA_SDK_PREFIX}/include/MESA)
#include_directories(${CMAKE_SOURCE_DIR}/include/support)
#include_directories(${CMAKE_SOURCE_DIR}/dealpkt)
-add_definitions(-D_BSD_SOURCE -D_BSD_SOURCE -D__BSD_SOURCE -D__FAVOR_BSD -DHAVE_NET_ETHERNET_H)
+add_definitions(${MEM_POOL_DEFINITIONS} -D_BSD_SOURCE -D_BSD_SOURCE -D__BSD_SOURCE -D__FAVOR_BSD -DHAVE_NET_ETHERNET_H)
add_library(dictator2 STATIC dictator.cpp dictator_debuger.cpp
D_internal/D_kernel_list.cpp D_internal/list_common.cpp