summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluwenpeng <[email protected]>2023-12-19 10:47:26 +0800
committerluwenpeng <[email protected]>2023-12-20 19:20:14 +0800
commit2c268791823cb9cf1f0d9bf6f50c4061a1efa436 (patch)
tree5c1806f184c2a2c003b6e555062b524f4a66342b
parent2e56bd810c956399305697ebfed0b683d88c1265 (diff)
implementation session manager
-rw-r--r--src/packet/packet.cpp48
-rw-r--r--src/packet/packet.h4
-rw-r--r--src/session/CMakeLists.txt19
-rw-r--r--src/session/gtest_session_manager.cpp1198
-rw-r--r--src/session/gtest_session_queue.cpp29
-rw-r--r--src/session/gtest_session_table.cpp28
-rw-r--r--src/session/session.cpp231
-rw-r--r--src/session/session.h48
-rw-r--r--src/session/session_manager.cpp595
-rw-r--r--src/session/session_manager.h32
-rw-r--r--src/session/session_private.h31
-rw-r--r--src/session/session_queue.cpp77
-rw-r--r--src/session/session_queue.h22
-rw-r--r--src/session/session_table.cpp42
-rw-r--r--src/session/session_table.h4
15 files changed, 2242 insertions, 166 deletions
diff --git a/src/packet/packet.cpp b/src/packet/packet.cpp
index bc3cf49..04af244 100644
--- a/src/packet/packet.cpp
+++ b/src/packet/packet.cpp
@@ -14,29 +14,28 @@
#define likely(expr) __builtin_expect((expr), 1)
#define unlikely(expr) __builtin_expect((expr), 0)
-#define LOG_PACKET "PACKET"
-#define PACKET_LOG_DATA_INSUFFICIENCY(type) \
- { \
- PACKET_LOG_ERROR("%s: layer: %s, data insufficiency", \
- LOG_PACKET, layer_type_tostring((type))); \
+#define PACKET_LOG_DATA_INSUFFICIENCY(type) \
+ { \
+ PACKET_LOG_ERROR("layer: %s, data insufficiency", \
+ layer_type_tostring((type))); \
}
-#define PACKET_LOG_UNSUPPORT_PROTO(tag, next_proto) \
- { \
- PACKET_LOG_ERROR("%s: %s: unsupport next proto %d", \
- LOG_PACKET, (tag), (next_proto)); \
+#define PACKET_LOG_UNSUPPORT_PROTO(tag, next_proto) \
+ { \
+ PACKET_LOG_ERROR("%s: unsupport next proto %d", \
+ (tag), (next_proto)); \
}
-#define PACKET_LOG_UNSUPPORT_ETHPROTO(tag, next_proto) \
- { \
- PACKET_LOG_ERROR("%s: %s: unsupport next proto %d: %s", \
- LOG_PACKET, (tag), (next_proto), ethproto_tostring(next_proto)); \
+#define PACKET_LOG_UNSUPPORT_ETHPROTO(tag, next_proto) \
+ { \
+ PACKET_LOG_ERROR("%s: unsupport next proto %d: %s", \
+ (tag), (next_proto), ethproto_tostring(next_proto)); \
}
-#define PACKET_LOG_UNSUPPORT_IPPROTO(tag, next_proto) \
- { \
- PACKET_LOG_ERROR("%s: %s: unsupport next proto %d: %s", \
- LOG_PACKET, (tag), (next_proto), ipproto_tostring(next_proto)); \
+#define PACKET_LOG_UNSUPPORT_IPPROTO(tag, next_proto) \
+ { \
+ PACKET_LOG_ERROR("%s: unsupport next proto %d: %s", \
+ (tag), (next_proto), ipproto_tostring(next_proto)); \
}
/******************************************************************************
@@ -428,8 +427,8 @@ static inline struct layer_record *get_free_layer(struct packet *handler)
(_layer)->pld_ptr = (_data) + (_hdr_len); \
(_layer)->pld_len = (_len) - (_hdr_len); \
(_handler)->layers_used++; \
- PACKET_LOG_DEBUG("%s: layer[%d/%d]: %s, hdr_offset: %d, hdr_ptr: %p, hdr_len: %d, pld_ptr: %p, pld_len: %d", \
- LOG_PACKET, (_handler)->layers_used - 1, (_handler)->layers_size, layer_type_tostring((_type)), \
+ PACKET_LOG_DEBUG("layer[%d/%d]: %s, hdr_offset: %d, hdr_ptr: %p, hdr_len: %d, pld_ptr: %p, pld_len: %d", \
+ (_handler)->layers_used - 1, (_handler)->layers_size, layer_type_tostring((_type)), \
(_layer)->hdr_offset, (_layer)->hdr_ptr, (_layer)->hdr_len, (_layer)->pld_ptr, (_layer)->pld_len); \
}
@@ -865,7 +864,7 @@ static inline const char *parse_ipv4(struct packet *handler, const char *data, u
// ip fragmented
if ((ntohs(hdr->ip_off) & IP_MF) || (ntohs(hdr->ip_off) & IP_OFFMASK))
{
- PACKET_LOG_DEBUG("%s: ip is fragmented", LOG_PACKET);
+ PACKET_LOG_DEBUG("ip is fragmented");
return layer->pld_ptr;
}
@@ -1471,14 +1470,5 @@ uint64_t packet_get_hash(const struct packet *handler, enum ldbc_method method,
return hash_value;
}
-#if 0
- char *inner_addr_str = tuple2_tostring(&inner_addr);
- char *outer_addr_str = tuple2_tostring(&outer_addr);
- printf("%s: outer_addr: %s, inner_addr: %s, dir: %s, hash_method: %s, hash_value: %lu\n",
- LOG_PACKET, outer_addr_str, inner_addr_str, (direction ? "E2I" : "I2E"), ldbc_method_tostring(method), hash_value);
- free(inner_addr_str);
- free(outer_addr_str);
-#endif
-
return hash_value;
}
diff --git a/src/packet/packet.h b/src/packet/packet.h
index 6b378c8..511cb0f 100644
--- a/src/packet/packet.h
+++ b/src/packet/packet.h
@@ -14,12 +14,12 @@ extern "C"
// #define PACKET_LOG_ERROR(format, ...) void(0)
#ifndef PACKET_LOG_ERROR
#define PACKET_LOG_ERROR(format, ...) \
- fprintf(stderr, "ERROR " format "\n", ##__VA_ARGS__);
+ fprintf(stderr, "ERROR (packet), " format "\n", ##__VA_ARGS__);
#endif
// #define PACKET_LOG_DEBUG(format, ...) void(0)
#ifndef PACKET_LOG_DEBUG
#define PACKET_LOG_DEBUG(format, ...) \
- fprintf(stderr, "DEBUG " format "\n", ##__VA_ARGS__);
+ fprintf(stderr, "DEBUG (packet), " format "\n", ##__VA_ARGS__);
#endif
enum layer_type
diff --git a/src/session/CMakeLists.txt b/src/session/CMakeLists.txt
index 2b9c426..13fdf5c 100644
--- a/src/session/CMakeLists.txt
+++ b/src/session/CMakeLists.txt
@@ -7,15 +7,16 @@ add_library(session_manager
session_pool.cpp
session_table.cpp
session_timer.cpp
- #session_manager.cpp
- )
+ session_queue.cpp
+ session_manager.cpp
+)
target_include_directories(session_manager PUBLIC ${CMAKE_SOURCE_DIR}/deps/uthash)
target_include_directories(session_manager PUBLIC ${CMAKE_SOURCE_DIR}/deps/timeout)
target_include_directories(session_manager PUBLIC ${CMAKE_SOURCE_DIR}/src/packet)
target_include_directories(session_manager PUBLIC ${CMAKE_SOURCE_DIR}/src/session)
target_include_directories(session_manager PUBLIC ${CMAKE_SOURCE_DIR}/src/timestamp)
target_include_directories(session_manager PUBLIC ${CMAKE_SOURCE_DIR}/src/tuple)
-target_link_libraries(session_manager timeout timestamp tuple)
+target_link_libraries(session_manager timeout timestamp tuple packet)
###############################################################################
# gtest
@@ -37,8 +38,18 @@ add_executable(gtest_session_timer gtest_session_timer.cpp)
target_include_directories(gtest_session_timer PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(gtest_session_timer session_manager gtest)
+add_executable(gtest_session_queue gtest_session_queue.cpp)
+target_include_directories(gtest_session_queue PUBLIC ${CMAKE_CURRENT_LIST_DIR})
+target_link_libraries(gtest_session_queue session_manager gtest)
+
+add_executable(gtest_session_manager gtest_session_manager.cpp)
+target_include_directories(gtest_session_manager PUBLIC ${CMAKE_CURRENT_LIST_DIR})
+target_link_libraries(gtest_session_manager session_manager gtest)
+
include(GoogleTest)
gtest_discover_tests(gtest_session)
gtest_discover_tests(gtest_session_pool)
gtest_discover_tests(gtest_session_table)
-gtest_discover_tests(gtest_session_timer) \ No newline at end of file
+gtest_discover_tests(gtest_session_timer)
+gtest_discover_tests(gtest_session_queue)
+gtest_discover_tests(gtest_session_manager) \ No newline at end of file
diff --git a/src/session/gtest_session_manager.cpp b/src/session/gtest_session_manager.cpp
new file mode 100644
index 0000000..e1f4110
--- /dev/null
+++ b/src/session/gtest_session_manager.cpp
@@ -0,0 +1,1198 @@
+#include <gtest/gtest.h>
+
+#include "session_private.h"
+#include "session_manager.h"
+#include "timestamp.h"
+
+/******************************************************************************
+ * test packet TCP
+ ******************************************************************************/
+
+/*
+ * Frame 1: 78 bytes on wire (624 bits), 78 bytes captured (624 bits) on interface en0, id 0
+ * Ethernet II, Src: Apple_0a:c5:ea (3c:a6:f6:0a:c5:ea), Dst: NewH3CTe_96:38:0e (48:73:97:96:38:0e)
+ * Destination: NewH3CTe_96:38:0e (48:73:97:96:38:0e)
+ * Source: Apple_0a:c5:ea (3c:a6:f6:0a:c5:ea)
+ * Type: IPv4 (0x0800)
+ * Internet Protocol Version 4, Src: 192.168.38.105, Dst: 93.184.216.34
+ * 0100 .... = Version: 4
+ * .... 0101 = Header Length: 20 bytes (5)
+ * Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
+ * 0000 00.. = Differentiated Services Codepoint: Default (0)
+ * .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
+ * Total Length: 64
+ * Identification: 0x0000 (0)
+ * 010. .... = Flags: 0x2, Don't fragment
+ * 0... .... = Reserved bit: Not set
+ * .1.. .... = Don't fragment: Set
+ * ..0. .... = More fragments: Not set
+ * ...0 0000 0000 0000 = Fragment Offset: 0
+ * Time to Live: 64
+ * Protocol: TCP (6)
+ * Header Checksum: 0x1dcc [correct]
+ * [Header checksum status: Good]
+ * [Calculated Checksum: 0x1dcc]
+ * Source Address: 192.168.38.105
+ * Destination Address: 93.184.216.34
+ * Transmission Control Protocol, Src Port: 60111, Dst Port: 80, Seq: 0, Len: 0
+ * Source Port: 60111
+ * Destination Port: 80
+ * [Stream index: 0]
+ * [Conversation completeness: Complete, WITH_DATA (31)]
+ * [TCP Segment Len: 0]
+ * Sequence Number: 0 (relative sequence number)
+ * Sequence Number (raw): 2089584940
+ * [Next Sequence Number: 1 (relative sequence number)]
+ * Acknowledgment Number: 0
+ * Acknowledgment number (raw): 0
+ * 1011 .... = Header Length: 44 bytes (11)
+ * Flags: 0x002 (SYN)
+ * 000. .... .... = Reserved: Not set
+ * ...0 .... .... = Accurate ECN: Not set
+ * .... 0... .... = Congestion Window Reduced: Not set
+ * .... .0.. .... = ECN-Echo: Not set
+ * .... ..0. .... = Urgent: Not set
+ * .... ...0 .... = Acknowledgment: Not set
+ * .... .... 0... = Push: Not set
+ * .... .... .0.. = Reset: Not set
+ * .... .... ..1. = Syn: Set
+ * [Expert Info (Chat/Sequence): Connection establish request (SYN): server port 80]
+ * [Connection establish request (SYN): server port 80]
+ * [Severity level: Chat]
+ * [Group: Sequence]
+ * .... .... ...0 = Fin: Not set
+ * [TCP Flags: ··········S·]
+ * Window: 65535
+ * [Calculated window size: 65535]
+ * Checksum: 0xca71 [correct]
+ * [Checksum Status: Good]
+ * [Calculated Checksum: 0xca71]
+ * Urgent Pointer: 0
+ * Options: (24 bytes), Maximum segment size, No-Operation (NOP), Window scale, No-Operation (NOP), No-Operation (NOP), Timestamps, SACK permitted, End of Option List (EOL), End of Option List (EOL)
+ * TCP Option - Maximum segment size: 1460 bytes
+ * Kind: Maximum Segment Size (2)
+ * Length: 4
+ * MSS Value: 1460
+ * TCP Option - No-Operation (NOP)
+ * Kind: No-Operation (1)
+ * TCP Option - Window scale: 6 (multiply by 64)
+ * Kind: Window Scale (3)
+ * Length: 3
+ * Shift count: 6
+ * [Multiplier: 64]
+ * TCP Option - No-Operation (NOP)
+ * Kind: No-Operation (1)
+ * TCP Option - No-Operation (NOP)
+ * Kind: No-Operation (1)
+ * TCP Option - Timestamps
+ * Kind: Time Stamp Option (8)
+ * Length: 10
+ * Timestamp value: 741028506: TSval 741028506, TSecr 0
+ * Timestamp echo reply: 0
+ * TCP Option - SACK permitted
+ * Kind: SACK Permitted (4)
+ * Length: 2
+ * TCP Option - End of Option List (EOL)
+ * Kind: End of Option List (0)
+ * TCP Option - End of Option List (EOL)
+ * Kind: End of Option List (0)
+ * [Timestamps]
+ * [Time since first frame in this TCP stream: 0.000000000 seconds]
+ * [Time since previous frame in this TCP stream: 0.000000000 seconds]
+ */
+
+unsigned char tcp_pkt1_c2s_syn[] = {
+ 0x48, 0x73, 0x97, 0x96, 0x38, 0x0e, 0x3c, 0xa6, 0xf6, 0x0a, 0xc5, 0xea, 0x08, 0x00, 0x45, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x40, 0x06, 0x1d, 0xcc,
+ 0xc0, 0xa8, 0x26, 0x69, 0x5d, 0xb8, 0xd8, 0x22, 0xea, 0xcf, 0x00, 0x50, 0x7c, 0x8c, 0x89, 0x2c, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xff, 0xff, 0xca, 0x71,
+ 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, 0x01, 0x03, 0x03, 0x06, 0x01, 0x01, 0x08, 0x0a, 0x2c, 0x2b, 0x32, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00};
+
+/*
+ * Frame 2: 74 bytes on wire (592 bits), 74 bytes captured (592 bits) on interface en0, id 0
+ * Ethernet II, Src: NewH3CTe_96:38:0e (48:73:97:96:38:0e), Dst: Apple_0a:c5:ea (3c:a6:f6:0a:c5:ea)
+ * Destination: Apple_0a:c5:ea (3c:a6:f6:0a:c5:ea)
+ * Source: NewH3CTe_96:38:0e (48:73:97:96:38:0e)
+ * Type: IPv4 (0x0800)
+ * Internet Protocol Version 4, Src: 93.184.216.34, Dst: 192.168.38.105
+ * 0100 .... = Version: 4
+ * .... 0101 = Header Length: 20 bytes (5)
+ * Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
+ * 0000 00.. = Differentiated Services Codepoint: Default (0)
+ * .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
+ * Total Length: 60
+ * Identification: 0x0000 (0)
+ * 010. .... = Flags: 0x2, Don't fragment
+ * 0... .... = Reserved bit: Not set
+ * .1.. .... = Don't fragment: Set
+ * ..0. .... = More fragments: Not set
+ * ...0 0000 0000 0000 = Fragment Offset: 0
+ * Time to Live: 42
+ * Protocol: TCP (6)
+ * Header Checksum: 0x33d0 [correct]
+ * [Header checksum status: Good]
+ * [Calculated Checksum: 0x33d0]
+ * Source Address: 93.184.216.34
+ * Destination Address: 192.168.38.105
+ * Transmission Control Protocol, Src Port: 80, Dst Port: 60111, Seq: 0, Ack: 1, Len: 0
+ * Source Port: 80
+ * Destination Port: 60111
+ * [Stream index: 0]
+ * [Conversation completeness: Complete, WITH_DATA (31)]
+ * [TCP Segment Len: 0]
+ * Sequence Number: 0 (relative sequence number)
+ * Sequence Number (raw): 1381452130
+ * [Next Sequence Number: 1 (relative sequence number)]
+ * Acknowledgment Number: 1 (relative ack number)
+ * Acknowledgment number (raw): 2089584941
+ * 1010 .... = Header Length: 40 bytes (10)
+ * Flags: 0x012 (SYN, ACK)
+ * 000. .... .... = Reserved: Not set
+ * ...0 .... .... = Accurate ECN: Not set
+ * .... 0... .... = Congestion Window Reduced: Not set
+ * .... .0.. .... = ECN-Echo: Not set
+ * .... ..0. .... = Urgent: Not set
+ * .... ...1 .... = Acknowledgment: Set
+ * .... .... 0... = Push: Not set
+ * .... .... .0.. = Reset: Not set
+ * .... .... ..1. = Syn: Set
+ * [Expert Info (Chat/Sequence): Connection establish acknowledge (SYN+ACK): server port 80]
+ * [Connection establish acknowledge (SYN+ACK): server port 80]
+ * [Severity level: Chat]
+ * [Group: Sequence]
+ * .... .... ...0 = Fin: Not set
+ * [TCP Flags: ·······A··S·]
+ * Window: 65535
+ * [Calculated window size: 65535]
+ * Checksum: 0xc5aa [correct]
+ * [Checksum Status: Good]
+ * [Calculated Checksum: 0xc5aa]
+ * Urgent Pointer: 0
+ * Options: (20 bytes), Maximum segment size, SACK permitted, Timestamps, No-Operation (NOP), Window scale
+ * TCP Option - Maximum segment size: 1300 bytes
+ * Kind: Maximum Segment Size (2)
+ * Length: 4
+ * MSS Value: 1300
+ * TCP Option - SACK permitted
+ * Kind: SACK Permitted (4)
+ * Length: 2
+ * TCP Option - Timestamps
+ * Kind: Time Stamp Option (8)
+ * Length: 10
+ * Timestamp value: 1215574570: TSval 1215574570, TSecr 741028506
+ * Timestamp echo reply: 741028506
+ * TCP Option - No-Operation (NOP)
+ * Kind: No-Operation (1)
+ * TCP Option - Window scale: 9 (multiply by 512)
+ * Kind: Window Scale (3)
+ * Length: 3
+ * Shift count: 9
+ * [Multiplier: 512]
+ * [Timestamps]
+ * [Time since first frame in this TCP stream: 0.262288000 seconds]
+ * [Time since previous frame in this TCP stream: 0.262288000 seconds]
+ * [SEQ/ACK analysis]
+ * [This is an ACK to the segment in frame: 1]
+ * [The RTT to ACK the segment was: 0.262288000 seconds]
+ * [iRTT: 0.262565000 seconds]
+ */
+
+unsigned char tcp_pkt2_s2c_syn_ack[] = {
+ 0x3c, 0xa6, 0xf6, 0x0a, 0xc5, 0xea, 0x48, 0x73, 0x97, 0x96, 0x38, 0x0e, 0x08, 0x00, 0x45, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x40, 0x00, 0x2a, 0x06, 0x33, 0xd0,
+ 0x5d, 0xb8, 0xd8, 0x22, 0xc0, 0xa8, 0x26, 0x69, 0x00, 0x50, 0xea, 0xcf, 0x52, 0x57, 0x49, 0x62, 0x7c, 0x8c, 0x89, 0x2d, 0xa0, 0x12, 0xff, 0xff, 0xc5, 0xaa,
+ 0x00, 0x00, 0x02, 0x04, 0x05, 0x14, 0x04, 0x02, 0x08, 0x0a, 0x48, 0x74, 0x32, 0x2a, 0x2c, 0x2b, 0x32, 0x9a, 0x01, 0x03, 0x03, 0x09};
+
+/*
+ * Frame 3: 66 bytes on wire (528 bits), 66 bytes captured (528 bits) on interface en0, id 0
+ * Ethernet II, Src: Apple_0a:c5:ea (3c:a6:f6:0a:c5:ea), Dst: NewH3CTe_96:38:0e (48:73:97:96:38:0e)
+ * Destination: NewH3CTe_96:38:0e (48:73:97:96:38:0e)
+ * Source: Apple_0a:c5:ea (3c:a6:f6:0a:c5:ea)
+ * Type: IPv4 (0x0800)
+ * Internet Protocol Version 4, Src: 192.168.38.105, Dst: 93.184.216.34
+ * 0100 .... = Version: 4
+ * .... 0101 = Header Length: 20 bytes (5)
+ * Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
+ * 0000 00.. = Differentiated Services Codepoint: Default (0)
+ * .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
+ * Total Length: 52
+ * Identification: 0x0000 (0)
+ * 010. .... = Flags: 0x2, Don't fragment
+ * 0... .... = Reserved bit: Not set
+ * .1.. .... = Don't fragment: Set
+ * ..0. .... = More fragments: Not set
+ * ...0 0000 0000 0000 = Fragment Offset: 0
+ * Time to Live: 64
+ * Protocol: TCP (6)
+ * Header Checksum: 0x1dd8 [correct]
+ * [Header checksum status: Good]
+ * [Calculated Checksum: 0x1dd8]
+ * Source Address: 192.168.38.105
+ * Destination Address: 93.184.216.34
+ * Transmission Control Protocol, Src Port: 60111, Dst Port: 80, Seq: 1, Ack: 1, Len: 0
+ * Source Port: 60111
+ * Destination Port: 80
+ * [Stream index: 0]
+ * [Conversation completeness: Complete, WITH_DATA (31)]
+ * [TCP Segment Len: 0]
+ * Sequence Number: 1 (relative sequence number)
+ * Sequence Number (raw): 2089584941
+ * [Next Sequence Number: 1 (relative sequence number)]
+ * Acknowledgment Number: 1 (relative ack number)
+ * Acknowledgment number (raw): 1381452131
+ * 1000 .... = Header Length: 32 bytes (8)
+ * Flags: 0x010 (ACK)
+ * 000. .... .... = Reserved: Not set
+ * ...0 .... .... = Accurate ECN: Not set
+ * .... 0... .... = Congestion Window Reduced: Not set
+ * .... .0.. .... = ECN-Echo: Not set
+ * .... ..0. .... = Urgent: Not set
+ * .... ...1 .... = Acknowledgment: Set
+ * .... .... 0... = Push: Not set
+ * .... .... .0.. = Reset: Not set
+ * .... .... ..0. = Syn: Not set
+ * .... .... ...0 = Fin: Not set
+ * [TCP Flags: ·······A····]
+ * Window: 2052
+ * [Calculated window size: 131328]
+ * [Window size scaling factor: 64]
+ * Checksum: 0xeace [correct]
+ * [Checksum Status: Good]
+ * [Calculated Checksum: 0xeace]
+ * Urgent Pointer: 0
+ * Options: (12 bytes), No-Operation (NOP), No-Operation (NOP), Timestamps
+ * TCP Option - No-Operation (NOP)
+ * Kind: No-Operation (1)
+ * TCP Option - No-Operation (NOP)
+ * Kind: No-Operation (1)
+ * TCP Option - Timestamps
+ * Kind: Time Stamp Option (8)
+ * Length: 10
+ * Timestamp value: 741028768: TSval 741028768, TSecr 1215574570
+ * Timestamp echo reply: 1215574570
+ * [Timestamps]
+ * [Time since first frame in this TCP stream: 0.262565000 seconds]
+ * [Time since previous frame in this TCP stream: 0.000277000 seconds]
+ * [SEQ/ACK analysis]
+ * [This is an ACK to the segment in frame: 2]
+ * [The RTT to ACK the segment was: 0.000277000 seconds]
+ * [iRTT: 0.262565000 seconds]
+ */
+
+unsigned char tcp_pkt3_c2s_ack[] = {
+ 0x48, 0x73, 0x97, 0x96, 0x38, 0x0e, 0x3c, 0xa6, 0xf6, 0x0a, 0xc5, 0xea, 0x08, 0x00, 0x45, 0x00, 0x00, 0x34, 0x00, 0x00, 0x40, 0x00, 0x40, 0x06, 0x1d, 0xd8,
+ 0xc0, 0xa8, 0x26, 0x69, 0x5d, 0xb8, 0xd8, 0x22, 0xea, 0xcf, 0x00, 0x50, 0x7c, 0x8c, 0x89, 0x2d, 0x52, 0x57, 0x49, 0x63, 0x80, 0x10, 0x08, 0x04, 0xea, 0xce,
+ 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x2c, 0x2b, 0x33, 0xa0, 0x48, 0x74, 0x32, 0x2a};
+
+/*
+ * Frame 9: 66 bytes on wire (528 bits), 66 bytes captured (528 bits) on interface en0, id 0
+ * Ethernet II, Src: Apple_0a:c5:ea (3c:a6:f6:0a:c5:ea), Dst: NewH3CTe_96:38:0e (48:73:97:96:38:0e)
+ * Destination: NewH3CTe_96:38:0e (48:73:97:96:38:0e)
+ * Source: Apple_0a:c5:ea (3c:a6:f6:0a:c5:ea)
+ * Type: IPv4 (0x0800)
+ * Internet Protocol Version 4, Src: 192.168.38.105, Dst: 93.184.216.34
+ * 0100 .... = Version: 4
+ * .... 0101 = Header Length: 20 bytes (5)
+ * Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
+ * 0000 00.. = Differentiated Services Codepoint: Default (0)
+ * .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
+ * Total Length: 52
+ * Identification: 0x0000 (0)
+ * 010. .... = Flags: 0x2, Don't fragment
+ * 0... .... = Reserved bit: Not set
+ * .1.. .... = Don't fragment: Set
+ * ..0. .... = More fragments: Not set
+ * ...0 0000 0000 0000 = Fragment Offset: 0
+ * Time to Live: 64
+ * Protocol: TCP (6)
+ * Header Checksum: 0x1dd8 [correct]
+ * [Header checksum status: Good]
+ * [Calculated Checksum: 0x1dd8]
+ * Source Address: 192.168.38.105
+ * Destination Address: 93.184.216.34
+ * Transmission Control Protocol, Src Port: 60111, Dst Port: 80, Seq: 80, Ack: 1608, Len: 0
+ * Source Port: 60111
+ * Destination Port: 80
+ * [Stream index: 0]
+ * [Conversation completeness: Complete, WITH_DATA (31)]
+ * [TCP Segment Len: 0]
+ * Sequence Number: 80 (relative sequence number)
+ * Sequence Number (raw): 2089585020
+ * [Next Sequence Number: 81 (relative sequence number)]
+ * Acknowledgment Number: 1608 (relative ack number)
+ * Acknowledgment number (raw): 1381453738
+ * 1000 .... = Header Length: 32 bytes (8)
+ * Flags: 0x011 (FIN, ACK)
+ * 000. .... .... = Reserved: Not set
+ * ...0 .... .... = Accurate ECN: Not set
+ * .... 0... .... = Congestion Window Reduced: Not set
+ * .... .0.. .... = ECN-Echo: Not set
+ * .... ..0. .... = Urgent: Not set
+ * .... ...1 .... = Acknowledgment: Set
+ * .... .... 0... = Push: Not set
+ * .... .... .0.. = Reset: Not set
+ * .... .... ..0. = Syn: Not set
+ * .... .... ...1 = Fin: Set
+ * [Expert Info (Chat/Sequence): Connection finish (FIN)]
+ * [Connection finish (FIN)]
+ * [Severity level: Chat]
+ * [Group: Sequence]
+ * [TCP Flags: ·······A···F]
+ * [Expert Info (Note/Sequence): This frame initiates the connection closing]
+ * [This frame initiates the connection closing]
+ * [Severity level: Note]
+ * [Group: Sequence]
+ * Window: 2048
+ * [Calculated window size: 131072]
+ * [Window size scaling factor: 64]
+ * Checksum: 0xe203 [correct]
+ * [Checksum Status: Good]
+ * [Calculated Checksum: 0xe203]
+ * Urgent Pointer: 0
+ * Options: (12 bytes), No-Operation (NOP), No-Operation (NOP), Timestamps
+ * TCP Option - No-Operation (NOP)
+ * Kind: No-Operation (1)
+ * TCP Option - No-Operation (NOP)
+ * Kind: No-Operation (1)
+ * TCP Option - Timestamps
+ * Kind: Time Stamp Option (8)
+ * Length: 10
+ * Timestamp value: 741029073: TSval 741029073, TSecr 1215574833
+ * Timestamp echo reply: 1215574833
+ * [Timestamps]
+ * [Time since first frame in this TCP stream: 0.568964000 seconds]
+ * [Time since previous frame in this TCP stream: 0.000565000 seconds]
+ */
+
+unsigned char tcp_pkt4_c2s_fin[] = {
+ 0x48, 0x73, 0x97, 0x96, 0x38, 0x0e, 0x3c, 0xa6, 0xf6, 0x0a, 0xc5, 0xea, 0x08, 0x00, 0x45, 0x00, 0x00, 0x34, 0x00, 0x00, 0x40, 0x00, 0x40, 0x06, 0x1d, 0xd8,
+ 0xc0, 0xa8, 0x26, 0x69, 0x5d, 0xb8, 0xd8, 0x22, 0xea, 0xcf, 0x00, 0x50, 0x7c, 0x8c, 0x89, 0x7c, 0x52, 0x57, 0x4f, 0xaa, 0x80, 0x11, 0x08, 0x00, 0xe2, 0x03,
+ 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x2c, 0x2b, 0x34, 0xd1, 0x48, 0x74, 0x33, 0x31};
+
+/*
+ * Frame 10: 66 bytes on wire (528 bits), 66 bytes captured (528 bits) on interface en0, id 0
+ * Ethernet II, Src: NewH3CTe_96:38:0e (48:73:97:96:38:0e), Dst: Apple_0a:c5:ea (3c:a6:f6:0a:c5:ea)
+ * Destination: Apple_0a:c5:ea (3c:a6:f6:0a:c5:ea)
+ * Source: NewH3CTe_96:38:0e (48:73:97:96:38:0e)
+ * Type: IPv4 (0x0800)
+ * Internet Protocol Version 4, Src: 93.184.216.34, Dst: 192.168.38.105
+ * 0100 .... = Version: 4
+ * .... 0101 = Header Length: 20 bytes (5)
+ * Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
+ * 0000 00.. = Differentiated Services Codepoint: Default (0)
+ * .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
+ * Total Length: 52
+ * Identification: 0xd6b3 (54963)
+ * 000. .... = Flags: 0x0
+ * 0... .... = Reserved bit: Not set
+ * .0.. .... = Don't fragment: Not set
+ * ..0. .... = More fragments: Not set
+ * ...0 0000 0000 0000 = Fragment Offset: 0
+ * Time to Live: 42
+ * Protocol: TCP (6)
+ * Header Checksum: 0x9d24 [correct]
+ * [Header checksum status: Good]
+ * [Calculated Checksum: 0x9d24]
+ * Source Address: 93.184.216.34
+ * Destination Address: 192.168.38.105
+ * Transmission Control Protocol, Src Port: 80, Dst Port: 60111, Seq: 1608, Ack: 81, Len: 0
+ * Source Port: 80
+ * Destination Port: 60111
+ * [Stream index: 0]
+ * [Conversation completeness: Complete, WITH_DATA (31)]
+ * [TCP Segment Len: 0]
+ * Sequence Number: 1608 (relative sequence number)
+ * Sequence Number (raw): 1381453738
+ * [Next Sequence Number: 1609 (relative sequence number)]
+ * Acknowledgment Number: 81 (relative ack number)
+ * Acknowledgment number (raw): 2089585021
+ * 1000 .... = Header Length: 32 bytes (8)
+ * Flags: 0x011 (FIN, ACK)
+ * 000. .... .... = Reserved: Not set
+ * ...0 .... .... = Accurate ECN: Not set
+ * .... 0... .... = Congestion Window Reduced: Not set
+ * .... .0.. .... = ECN-Echo: Not set
+ * .... ..0. .... = Urgent: Not set
+ * .... ...1 .... = Acknowledgment: Set
+ * .... .... 0... = Push: Not set
+ * .... .... .0.. = Reset: Not set
+ * .... .... ..0. = Syn: Not set
+ * .... .... ...1 = Fin: Set
+ * [Expert Info (Chat/Sequence): Connection finish (FIN)]
+ * [Connection finish (FIN)]
+ * [Severity level: Chat]
+ * [Group: Sequence]
+ * [TCP Flags: ·······A···F]
+ * [Expert Info (Note/Sequence): This frame undergoes the connection closing]
+ * [This frame undergoes the connection closing]
+ * [Severity level: Note]
+ * [Group: Sequence]
+ * Window: 128
+ * [Calculated window size: 65536]
+ * [Window size scaling factor: 512]
+ * Checksum: 0xe851 [correct]
+ * [Checksum Status: Good]
+ * [Calculated Checksum: 0xe851]
+ * Urgent Pointer: 0
+ * Options: (12 bytes), No-Operation (NOP), No-Operation (NOP), Timestamps
+ * TCP Option - No-Operation (NOP)
+ * Kind: No-Operation (1)
+ * TCP Option - No-Operation (NOP)
+ * Kind: No-Operation (1)
+ * TCP Option - Timestamps
+ * Kind: Time Stamp Option (8)
+ * Length: 10
+ * Timestamp value: 1215575138: TSval 1215575138, TSecr 741029073
+ * Timestamp echo reply: 741029073
+ * [Timestamps]
+ * [Time since first frame in this TCP stream: 0.876568000 seconds]
+ * [Time since previous frame in this TCP stream: 0.307604000 seconds]
+ * [SEQ/ACK analysis]
+ * [This is an ACK to the segment in frame: 9]
+ * [The RTT to ACK the segment was: 0.307604000 seconds]
+ * [iRTT: 0.262565000 seconds]
+ */
+
+unsigned char tcp_pkt5_s2c_fin[] = {
+ 0x3c, 0xa6, 0xf6, 0x0a, 0xc5, 0xea, 0x48, 0x73, 0x97, 0x96, 0x38, 0x0e, 0x08, 0x00, 0x45, 0x00, 0x00, 0x34, 0xd6, 0xb3, 0x00, 0x00, 0x2a, 0x06, 0x9d, 0x24,
+ 0x5d, 0xb8, 0xd8, 0x22, 0xc0, 0xa8, 0x26, 0x69, 0x00, 0x50, 0xea, 0xcf, 0x52, 0x57, 0x4f, 0xaa, 0x7c, 0x8c, 0x89, 0x7d, 0x80, 0x11, 0x00, 0x80, 0xe8, 0x51,
+ 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x48, 0x74, 0x34, 0x62, 0x2c, 0x2b, 0x34, 0xd1};
+
+/******************************************************************************
+ * test packet UDP
+ ******************************************************************************/
+
+/*
+ * Frame 1: 74 bytes on wire (592 bits), 74 bytes captured (592 bits) on interface en0, id 0
+ * Ethernet II, Src: Apple_0a:c5:ea (3c:a6:f6:0a:c5:ea), Dst: NewH3CTe_96:38:0e (48:73:97:96:38:0e)
+ * Destination: NewH3CTe_96:38:0e (48:73:97:96:38:0e)
+ * Source: Apple_0a:c5:ea (3c:a6:f6:0a:c5:ea)
+ * Type: IPv4 (0x0800)
+ * Internet Protocol Version 4, Src: 192.168.38.105, Dst: 121.14.154.93
+ * 0100 .... = Version: 4
+ * .... 0101 = Header Length: 20 bytes (5)
+ * Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
+ * 0000 00.. = Differentiated Services Codepoint: Default (0)
+ * .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
+ * Total Length: 60
+ * Identification: 0xaef9 (44793)
+ * 000. .... = Flags: 0x0
+ * 0... .... = Reserved bit: Not set
+ * .0.. .... = Don't fragment: Not set
+ * ..0. .... = More fragments: Not set
+ * ...0 0000 0000 0000 = Fragment Offset: 0
+ * Time to Live: 64
+ * Protocol: UDP (17)
+ * Header Checksum: 0xd13a [correct]
+ * [Header checksum status: Good]
+ * [Calculated Checksum: 0xd13a]
+ * Source Address: 192.168.38.105
+ * Destination Address: 121.14.154.93
+ * User Datagram Protocol, Src Port: 61099, Dst Port: 53
+ * Source Port: 61099
+ * Destination Port: 53
+ * Length: 40
+ * Checksum: 0xdcf1 [correct]
+ * [Calculated Checksum: 0xdcf1]
+ * [Checksum Status: Good]
+ * [Stream index: 0]
+ * [Timestamps]
+ * [Time since first frame: 0.000000000 seconds]
+ * [Time since previous frame: 0.000000000 seconds]
+ * UDP payload (32 bytes)
+ * Domain Name System (query)
+ * Transaction ID: 0xa5af
+ * Flags: 0x0100 Standard query
+ * 0... .... .... .... = Response: Message is a query
+ * .000 0... .... .... = Opcode: Standard query (0)
+ * .... ..0. .... .... = Truncated: Message is not truncated
+ * .... ...1 .... .... = Recursion desired: Do query recursively
+ * .... .... .0.. .... = Z: reserved (0)
+ * .... .... ...0 .... = Non-authenticated data: Unacceptable
+ * Questions: 1
+ * Answer RRs: 0
+ * Authority RRs: 0
+ * Additional RRs: 0
+ * Queries
+ * www.badssl.com: type A, class IN
+ * Name: www.badssl.com
+ * [Name Length: 14]
+ * [Label Count: 3]
+ * Type: A (Host Address) (1)
+ * Class: IN (0x0001)
+ * [Response In: 2]
+ */
+
+unsigned char udp_pkt1_dns_req[] = {
+ 0x48, 0x73, 0x97, 0x96, 0x38, 0x0e, 0x3c, 0xa6, 0xf6, 0x0a, 0xc5, 0xea, 0x08, 0x00, 0x45, 0x00, 0x00, 0x3c, 0xae, 0xf9, 0x00, 0x00, 0x40, 0x11, 0xd1, 0x3a,
+ 0xc0, 0xa8, 0x26, 0x69, 0x79, 0x0e, 0x9a, 0x5d, 0xee, 0xab, 0x00, 0x35, 0x00, 0x28, 0xdc, 0xf1, 0xa5, 0xaf, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x03, 0x77, 0x77, 0x77, 0x06, 0x62, 0x61, 0x64, 0x73, 0x73, 0x6c, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01};
+
+/*
+ * Frame 2: 550 bytes on wire (4400 bits), 550 bytes captured (4400 bits) on interface en0, id 0
+ * Ethernet II, Src: NewH3CTe_96:38:0e (48:73:97:96:38:0e), Dst: Apple_0a:c5:ea (3c:a6:f6:0a:c5:ea)
+ * Destination: Apple_0a:c5:ea (3c:a6:f6:0a:c5:ea)
+ * Source: NewH3CTe_96:38:0e (48:73:97:96:38:0e)
+ * Type: IPv4 (0x0800)
+ * Internet Protocol Version 4, Src: 121.14.154.93, Dst: 192.168.38.105
+ * 0100 .... = Version: 4
+ * .... 0101 = Header Length: 20 bytes (5)
+ * Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
+ * 0000 00.. = Differentiated Services Codepoint: Default (0)
+ * .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
+ * Total Length: 536
+ * Identification: 0xb578 (46456)
+ * 000. .... = Flags: 0x0
+ * 0... .... = Reserved bit: Not set
+ * .0.. .... = Don't fragment: Not set
+ * ..0. .... = More fragments: Not set
+ * ...0 0000 0000 0000 = Fragment Offset: 0
+ * Time to Live: 46
+ * Protocol: UDP (17)
+ * Header Checksum: 0xdadf [correct]
+ * [Header checksum status: Good]
+ * [Calculated Checksum: 0xdadf]
+ * Source Address: 121.14.154.93
+ * Destination Address: 192.168.38.105
+ * User Datagram Protocol, Src Port: 53, Dst Port: 61099
+ * Source Port: 53
+ * Destination Port: 61099
+ * Length: 516
+ * Checksum: 0x9aca [correct]
+ * [Calculated Checksum: 0x9aca]
+ * [Checksum Status: Good]
+ * [Stream index: 0]
+ * [Timestamps]
+ * [Time since first frame: 0.525915000 seconds]
+ * [Time since previous frame: 0.525915000 seconds]
+ * UDP payload (508 bytes)
+ * Domain Name System (response)
+ * Transaction ID: 0xa5af
+ * Flags: 0x8180 Standard query response, No error
+ * 1... .... .... .... = Response: Message is a response
+ * .000 0... .... .... = Opcode: Standard query (0)
+ * .... .0.. .... .... = Authoritative: Server is not an authority for domain
+ * .... ..0. .... .... = Truncated: Message is not truncated
+ * .... ...1 .... .... = Recursion desired: Do query recursively
+ * .... .... 1... .... = Recursion available: Server can do recursive queries
+ * .... .... .0.. .... = Z: reserved (0)
+ * .... .... ..0. .... = Answer authenticated: Answer/authority portion was not authenticated by the server
+ * .... .... ...0 .... = Non-authenticated data: Unacceptable
+ * .... .... .... 0000 = Reply code: No error (0)
+ * Questions: 1
+ * Answer RRs: 1
+ * Authority RRs: 13
+ * Additional RRs: 14
+ * Queries
+ * www.badssl.com: type A, class IN
+ * Name: www.badssl.com
+ * [Name Length: 14]
+ * [Label Count: 3]
+ * Type: A (Host Address) (1)
+ * Class: IN (0x0001)
+ * Answers
+ * www.badssl.com: type A, class IN, addr 104.154.89.105
+ * Name: www.badssl.com
+ * Type: A (Host Address) (1)
+ * Class: IN (0x0001)
+ * Time to live: 3600 (1 hour)
+ * Data length: 4
+ * Address: 104.154.89.105
+ * Authoritative nameservers
+ * com: type NS, class IN, ns b.gtld-servers.net
+ * Name: com
+ * Type: NS (authoritative Name Server) (2)
+ * Class: IN (0x0001)
+ * Time to live: 108314 (1 day, 6 hours, 5 minutes, 14 seconds)
+ * Data length: 20
+ * Name Server: b.gtld-servers.net
+ * com: type NS, class IN, ns e.gtld-servers.net
+ * Name: com
+ * Type: NS (authoritative Name Server) (2)
+ * Class: IN (0x0001)
+ * Time to live: 108314 (1 day, 6 hours, 5 minutes, 14 seconds)
+ * Data length: 4
+ * Name Server: e.gtld-servers.net
+ * com: type NS, class IN, ns c.gtld-servers.net
+ * Name: com
+ * Type: NS (authoritative Name Server) (2)
+ * Class: IN (0x0001)
+ * Time to live: 108314 (1 day, 6 hours, 5 minutes, 14 seconds)
+ * Data length: 4
+ * Name Server: c.gtld-servers.net
+ * com: type NS, class IN, ns f.gtld-servers.net
+ * Name: com
+ * Type: NS (authoritative Name Server) (2)
+ * Class: IN (0x0001)
+ * Time to live: 108314 (1 day, 6 hours, 5 minutes, 14 seconds)
+ * Data length: 4
+ * Name Server: f.gtld-servers.net
+ * com: type NS, class IN, ns a.gtld-servers.net
+ * Name: com
+ * Type: NS (authoritative Name Server) (2)
+ * Class: IN (0x0001)
+ * Time to live: 108314 (1 day, 6 hours, 5 minutes, 14 seconds)
+ * Data length: 4
+ * Name Server: a.gtld-servers.net
+ * com: type NS, class IN, ns k.gtld-servers.net
+ * Name: com
+ * Type: NS (authoritative Name Server) (2)
+ * Class: IN (0x0001)
+ * Time to live: 108314 (1 day, 6 hours, 5 minutes, 14 seconds)
+ * Data length: 4
+ * Name Server: k.gtld-servers.net
+ * com: type NS, class IN, ns h.gtld-servers.net
+ * Name: com
+ * Type: NS (authoritative Name Server) (2)
+ * Class: IN (0x0001)
+ * Time to live: 108314 (1 day, 6 hours, 5 minutes, 14 seconds)
+ * Data length: 4
+ * Name Server: h.gtld-servers.net
+ * com: type NS, class IN, ns d.gtld-servers.net
+ * Name: com
+ * Type: NS (authoritative Name Server) (2)
+ * Class: IN (0x0001)
+ * Time to live: 108314 (1 day, 6 hours, 5 minutes, 14 seconds)
+ * Data length: 4
+ * Name Server: d.gtld-servers.net
+ * com: type NS, class IN, ns g.gtld-servers.net
+ * Name: com
+ * Type: NS (authoritative Name Server) (2)
+ * Class: IN (0x0001)
+ * Time to live: 108314 (1 day, 6 hours, 5 minutes, 14 seconds)
+ * Data length: 4
+ * Name Server: g.gtld-servers.net
+ * com: type NS, class IN, ns i.gtld-servers.net
+ * Name: com
+ * Type: NS (authoritative Name Server) (2)
+ * Class: IN (0x0001)
+ * Time to live: 108314 (1 day, 6 hours, 5 minutes, 14 seconds)
+ * Data length: 4
+ * Name Server: i.gtld-servers.net
+ * com: type NS, class IN, ns m.gtld-servers.net
+ * Name: com
+ * Type: NS (authoritative Name Server) (2)
+ * Class: IN (0x0001)
+ * Time to live: 108314 (1 day, 6 hours, 5 minutes, 14 seconds)
+ * Data length: 4
+ * Name Server: m.gtld-servers.net
+ * com: type NS, class IN, ns l.gtld-servers.net
+ * Name: com
+ * Type: NS (authoritative Name Server) (2)
+ * Class: IN (0x0001)
+ * Time to live: 108314 (1 day, 6 hours, 5 minutes, 14 seconds)
+ * Data length: 4
+ * Name Server: l.gtld-servers.net
+ * com: type NS, class IN, ns j.gtld-servers.net
+ * Name: com
+ * Type: NS (authoritative Name Server) (2)
+ * Class: IN (0x0001)
+ * Time to live: 108314 (1 day, 6 hours, 5 minutes, 14 seconds)
+ * Data length: 4
+ * Name Server: j.gtld-servers.net
+ * Additional records
+ * a.gtld-servers.net: type A, class IN, addr 192.5.6.30
+ * Name: a.gtld-servers.net
+ * Type: A (Host Address) (1)
+ * Class: IN (0x0001)
+ * Time to live: 22363 (6 hours, 12 minutes, 43 seconds)
+ * Data length: 4
+ * Address: 192.5.6.30
+ * b.gtld-servers.net: type A, class IN, addr 192.33.14.30
+ * Name: b.gtld-servers.net
+ * Type: A (Host Address) (1)
+ * Class: IN (0x0001)
+ * Time to live: 94262 (1 day, 2 hours, 11 minutes, 2 seconds)
+ * Data length: 4
+ * Address: 192.33.14.30
+ * c.gtld-servers.net: type A, class IN, addr 192.26.92.30
+ * Name: c.gtld-servers.net
+ * Type: A (Host Address) (1)
+ * Class: IN (0x0001)
+ * Time to live: 94829 (1 day, 2 hours, 20 minutes, 29 seconds)
+ * Data length: 4
+ * Address: 192.26.92.30
+ * d.gtld-servers.net: type A, class IN, addr 192.31.80.30
+ * Name: d.gtld-servers.net
+ * Type: A (Host Address) (1)
+ * Class: IN (0x0001)
+ * Time to live: 94683 (1 day, 2 hours, 18 minutes, 3 seconds)
+ * Data length: 4
+ * Address: 192.31.80.30
+ * e.gtld-servers.net: type A, class IN, addr 192.12.94.30
+ * Name: e.gtld-servers.net
+ * Type: A (Host Address) (1)
+ * Class: IN (0x0001)
+ * Time to live: 95571 (1 day, 2 hours, 32 minutes, 51 seconds)
+ * Data length: 4
+ * Address: 192.12.94.30
+ * f.gtld-servers.net: type A, class IN, addr 192.35.51.30
+ * Name: f.gtld-servers.net
+ * Type: A (Host Address) (1)
+ * Class: IN (0x0001)
+ * Time to live: 94683 (1 day, 2 hours, 18 minutes, 3 seconds)
+ * Data length: 4
+ * Address: 192.35.51.30
+ * g.gtld-servers.net: type A, class IN, addr 192.42.93.30
+ * Name: g.gtld-servers.net
+ * Type: A (Host Address) (1)
+ * Class: IN (0x0001)
+ * Time to live: 96370 (1 day, 2 hours, 46 minutes, 10 seconds)
+ * Data length: 4
+ * Address: 192.42.93.30
+ * h.gtld-servers.net: type A, class IN, addr 192.54.112.30
+ * Name: h.gtld-servers.net
+ * Type: A (Host Address) (1)
+ * Class: IN (0x0001)
+ * Time to live: 96885 (1 day, 2 hours, 54 minutes, 45 seconds)
+ * Data length: 4
+ * Address: 192.54.112.30
+ * i.gtld-servers.net: type A, class IN, addr 192.43.172.30
+ * Name: i.gtld-servers.net
+ * Type: A (Host Address) (1)
+ * Class: IN (0x0001)
+ * Time to live: 95037 (1 day, 2 hours, 23 minutes, 57 seconds)
+ * Data length: 4
+ * Address: 192.43.172.30
+ * j.gtld-servers.net: type A, class IN, addr 192.48.79.30
+ * Name: j.gtld-servers.net
+ * Type: A (Host Address) (1)
+ * Class: IN (0x0001)
+ * Time to live: 94829 (1 day, 2 hours, 20 minutes, 29 seconds)
+ * Data length: 4
+ * Address: 192.48.79.30
+ * k.gtld-servers.net: type A, class IN, addr 192.52.178.30
+ * Name: k.gtld-servers.net
+ * Type: A (Host Address) (1)
+ * Class: IN (0x0001)
+ * Time to live: 96885 (1 day, 2 hours, 54 minutes, 45 seconds)
+ * Data length: 4
+ * Address: 192.52.178.30
+ * l.gtld-servers.net: type A, class IN, addr 192.41.162.30
+ * Name: l.gtld-servers.net
+ * Type: A (Host Address) (1)
+ * Class: IN (0x0001)
+ * Time to live: 96885 (1 day, 2 hours, 54 minutes, 45 seconds)
+ * Data length: 4
+ * Address: 192.41.162.30
+ * m.gtld-servers.net: type A, class IN, addr 192.55.83.30
+ * Name: m.gtld-servers.net
+ * Type: A (Host Address) (1)
+ * Class: IN (0x0001)
+ * Time to live: 94829 (1 day, 2 hours, 20 minutes, 29 seconds)
+ * Data length: 4
+ * Address: 192.55.83.30
+ * a.gtld-servers.net: type AAAA, class IN, addr 2001:503:a83e::2:30
+ * Name: a.gtld-servers.net
+ * Type: AAAA (IPv6 Address) (28)
+ * Class: IN (0x0001)
+ * Time to live: 108314 (1 day, 6 hours, 5 minutes, 14 seconds)
+ * Data length: 16
+ * AAAA Address: 2001:503:a83e::2:30
+ * [Request In: 1]
+ * [Time: 0.525915000 seconds]
+ */
+
+unsigned char udp_pkt2_dns_resp[] = {
+ 0x3c, 0xa6, 0xf6, 0x0a, 0xc5, 0xea, 0x48, 0x73, 0x97, 0x96, 0x38, 0x0e, 0x08, 0x00, 0x45, 0x00, 0x02, 0x18, 0xb5, 0x78, 0x00, 0x00, 0x2e, 0x11, 0xda, 0xdf,
+ 0x79, 0x0e, 0x9a, 0x5d, 0xc0, 0xa8, 0x26, 0x69, 0x00, 0x35, 0xee, 0xab, 0x02, 0x04, 0x9a, 0xca, 0xa5, 0xaf, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0d,
+ 0x00, 0x0e, 0x03, 0x77, 0x77, 0x77, 0x06, 0x62, 0x61, 0x64, 0x73, 0x73, 0x6c, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01,
+ 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x04, 0x68, 0x9a, 0x59, 0x69, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x14, 0x01, 0x62,
+ 0x0c, 0x67, 0x74, 0x6c, 0x64, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x03, 0x6e, 0x65, 0x74, 0x00, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01,
+ 0xa7, 0x1a, 0x00, 0x04, 0x01, 0x65, 0xc0, 0x3e, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04, 0x01, 0x63, 0xc0, 0x3e, 0xc0, 0x17,
+ 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04, 0x01, 0x66, 0xc0, 0x3e, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04,
+ 0x01, 0x61, 0xc0, 0x3e, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04, 0x01, 0x6b, 0xc0, 0x3e, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01,
+ 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04, 0x01, 0x68, 0xc0, 0x3e, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04, 0x01, 0x64, 0xc0, 0x3e,
+ 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04, 0x01, 0x67, 0xc0, 0x3e, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a,
+ 0x00, 0x04, 0x01, 0x69, 0xc0, 0x3e, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04, 0x01, 0x6d, 0xc0, 0x3e, 0xc0, 0x17, 0x00, 0x02,
+ 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04, 0x01, 0x6c, 0xc0, 0x3e, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04, 0x01, 0x6a,
+ 0xc0, 0x3e, 0xc0, 0x8c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x57, 0x5b, 0x00, 0x04, 0xc0, 0x05, 0x06, 0x1e, 0xc0, 0x3c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
+ 0x70, 0x36, 0x00, 0x04, 0xc0, 0x21, 0x0e, 0x1e, 0xc0, 0x6c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x72, 0x6d, 0x00, 0x04, 0xc0, 0x1a, 0x5c, 0x1e, 0xc0, 0xbc,
+ 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x71, 0xdb, 0x00, 0x04, 0xc0, 0x1f, 0x50, 0x1e, 0xc0, 0x5c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x75, 0x53, 0x00, 0x04,
+ 0xc0, 0x0c, 0x5e, 0x1e, 0xc0, 0x7c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x71, 0xdb, 0x00, 0x04, 0xc0, 0x23, 0x33, 0x1e, 0xc0, 0xcc, 0x00, 0x01, 0x00, 0x01,
+ 0x00, 0x01, 0x78, 0x72, 0x00, 0x04, 0xc0, 0x2a, 0x5d, 0x1e, 0xc0, 0xac, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x7a, 0x75, 0x00, 0x04, 0xc0, 0x36, 0x70, 0x1e,
+ 0xc0, 0xdc, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x73, 0x3d, 0x00, 0x04, 0xc0, 0x2b, 0xac, 0x1e, 0xc1, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x72, 0x6d,
+ 0x00, 0x04, 0xc0, 0x30, 0x4f, 0x1e, 0xc0, 0x9c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x7a, 0x75, 0x00, 0x04, 0xc0, 0x34, 0xb2, 0x1e, 0xc0, 0xfc, 0x00, 0x01,
+ 0x00, 0x01, 0x00, 0x01, 0x7a, 0x75, 0x00, 0x04, 0xc0, 0x29, 0xa2, 0x1e, 0xc0, 0xec, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x72, 0x6d, 0x00, 0x04, 0xc0, 0x37,
+ 0x53, 0x1e, 0xc0, 0x8c, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x10, 0x20, 0x01, 0x05, 0x03, 0xa8, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x30};
+
+/******************************************************************************
+ * plugin
+ ******************************************************************************/
+
+uint8_t PLUGIN_EX = 0;
+const char *plugin_ctx = "hello world";
+
+void plugin_session_ex_free(struct session *sess, uint8_t idx, void *ex_ptr, void *arg)
+{
+ printf("free ex data: %s\n", (char *)ex_ptr);
+ EXPECT_STREQ((char *)ex_ptr, "123");
+ free(ex_ptr);
+}
+
+void plugin_init(void)
+{
+ PLUGIN_EX = session_get_ex_new_index("PLUGIN_EX", plugin_session_ex_free, NULL);
+}
+
+void plugin_dispatch(struct session *sess, uint32_t event, void *arg)
+{
+ printf("\n");
+ printf("=> plugin_dispatch handle session: %p, event: \"%s\", arg: %s\n", sess, session_event_tostring((enum session_event)event), (const char *)arg);
+ session_dump(sess);
+ if (event == SESSION_EVENT_OPENING)
+ {
+ char *pluin_ex = strdup("123");
+ session_set_ex_data(sess, PLUGIN_EX, pluin_ex);
+ }
+ else
+ {
+ char *pluin_ex = (char *)session_get0_ex_data(sess, PLUGIN_EX);
+ EXPECT_STREQ(pluin_ex, "123");
+ }
+ printf("<= plugin_dispatch\n");
+ printf("\n");
+}
+
+/******************************************************************************
+ * test case
+ ******************************************************************************/
+
+#if 1
+TEST(SESSION_MANAGER, INIT_TO_OPENING_BY_TCP_SYN)
+{
+ char buffer[1024];
+ uint64_t max_session_num = 16;
+ struct packet pkt;
+ struct session *sess = NULL;
+ struct session_manager *mgr = NULL;
+
+ timestamp_update();
+ plugin_init();
+
+ mgr = session_manager_create(max_session_num);
+ EXPECT_TRUE(mgr != NULL);
+ session_manager_set_session_eventcb(mgr, plugin_dispatch, (void *)plugin_ctx);
+ session_manager_set_packet_timeout(mgr, 1000);
+ session_manager_set_closing_timeout(mgr, 2000);
+
+ packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
+ sess = session_manager_find_session(mgr, &pkt);
+ EXPECT_TRUE(sess);
+
+ // check session info
+ EXPECT_TRUE(session_get_id(sess) == 0);
+ memset(buffer, 0, sizeof(buffer));
+ tuple6_tostring(session_get0_tuple6(sess), buffer, sizeof(buffer));
+ EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, zone: 0");
+ EXPECT_TRUE(session_get_tuple6_dir(sess) == SESSION_DIR_C2S);
+ EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_OPENING);
+ EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
+ EXPECT_TRUE(session_get_c2s_bytes(sess) == 78);
+ EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
+ EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
+ EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
+ EXPECT_TRUE(session_get0_c2s_1st_md(sess) == NULL);
+ EXPECT_TRUE(session_get0_s2c_1st_md(sess) == NULL);
+ EXPECT_TRUE(session_get_create_time(sess) != 0);
+ EXPECT_TRUE(session_get_last_time(sess) != 0);
+ EXPECT_TRUE(session_get_create_time(sess) == session_get_last_time(sess));
+ EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
+ EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
+ EXPECT_TRUE((uint64_t)session_get0_ex_data(sess, tcp_builtin_ex) == TCP_SYN_RECVED);
+
+ // check session manager info
+ EXPECT_TRUE(session_manager_get_tcp_opening_sess_num(mgr) == 1);
+ EXPECT_TRUE(session_manager_get_tcp_closing_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_tcp_active_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_opening_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_closing_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_active_sess_num(mgr) == 0);
+
+ for (int i = 0; i < 4; i++)
+ {
+ timestamp_update();
+ session_manager_dispatch(mgr);
+ sleep(1);
+ }
+
+ // check sess mgr
+ EXPECT_TRUE(session_manager_get_tcp_opening_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_tcp_closing_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_tcp_active_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_opening_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_closing_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_active_sess_num(mgr) == 0);
+
+ // destory
+ session_manager_destroy(mgr);
+}
+#endif
+
+#if 1
+TEST(SESSION_MANAGER, INIT_TO_OPENING_BY_TCP_SYNACK)
+{
+ char buffer[1024];
+ uint64_t max_session_num = 16;
+ struct packet pkt;
+ struct session *sess = NULL;
+ struct session_manager *mgr = NULL;
+
+ timestamp_update();
+ plugin_init();
+
+ mgr = session_manager_create(max_session_num);
+ EXPECT_TRUE(mgr != NULL);
+ session_manager_set_session_eventcb(mgr, plugin_dispatch, (void *)plugin_ctx);
+ session_manager_set_packet_timeout(mgr, 1000);
+ session_manager_set_closing_timeout(mgr, 2000);
+
+ packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
+ sess = session_manager_find_session(mgr, &pkt);
+ EXPECT_TRUE(sess);
+
+ // check session info
+ EXPECT_TRUE(session_get_id(sess) == 0);
+ memset(buffer, 0, sizeof(buffer));
+ tuple6_tostring(session_get0_tuple6(sess), buffer, sizeof(buffer));
+ EXPECT_STREQ(buffer, "93.184.216.34:80 -> 192.168.38.105:60111, proto: 6, zone: 0");
+ EXPECT_TRUE(session_get_tuple6_dir(sess) == SESSION_DIR_S2C);
+ EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_OPENING);
+ EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
+ EXPECT_TRUE(session_get_c2s_bytes(sess) == 0);
+ EXPECT_TRUE(session_get_s2c_bytes(sess) == 74);
+ EXPECT_TRUE(session_get_c2s_packets(sess) == 0);
+ EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
+ EXPECT_TRUE(session_get0_c2s_1st_md(sess) == NULL);
+ EXPECT_TRUE(session_get0_s2c_1st_md(sess) == NULL);
+ EXPECT_TRUE(session_get_create_time(sess) != 0);
+ EXPECT_TRUE(session_get_last_time(sess) != 0);
+ EXPECT_TRUE(session_get_create_time(sess) == session_get_last_time(sess));
+ EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
+ EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
+ EXPECT_TRUE((uint64_t)session_get0_ex_data(sess, tcp_builtin_ex) == TCP_SYNACK_RECVED);
+
+ // check session manager info
+ EXPECT_TRUE(session_manager_get_tcp_opening_sess_num(mgr) == 1);
+ EXPECT_TRUE(session_manager_get_tcp_closing_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_tcp_active_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_opening_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_closing_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_active_sess_num(mgr) == 0);
+
+ for (int i = 0; i < 4; i++)
+ {
+ timestamp_update();
+ session_manager_dispatch(mgr);
+ sleep(1);
+ }
+
+ // check sess mgr
+ EXPECT_TRUE(session_manager_get_tcp_opening_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_tcp_closing_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_tcp_active_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_opening_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_closing_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_active_sess_num(mgr) == 0);
+
+ // destory
+ session_manager_destroy(mgr);
+}
+#endif
+
+#if 1
+TEST(SESSION_MANAGER, INIT_TO_ACTIVE_BY_UDP_C2S)
+{
+ char buffer[1024];
+ uint64_t max_session_num = 16;
+ struct packet pkt;
+ struct session *sess = NULL;
+ struct session_manager *mgr = NULL;
+
+ timestamp_update();
+ plugin_init();
+
+ mgr = session_manager_create(max_session_num);
+ EXPECT_TRUE(mgr != NULL);
+ session_manager_set_session_eventcb(mgr, plugin_dispatch, (void *)plugin_ctx);
+ session_manager_set_packet_timeout(mgr, 1000);
+ session_manager_set_closing_timeout(mgr, 2000);
+
+ packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req));
+ sess = session_manager_find_session(mgr, &pkt);
+ EXPECT_TRUE(sess);
+
+ // check session info
+ EXPECT_TRUE(session_get_id(sess) == 0);
+ memset(buffer, 0, sizeof(buffer));
+ tuple6_tostring(session_get0_tuple6(sess), buffer, sizeof(buffer));
+ EXPECT_STREQ(buffer, "192.168.38.105:61099 -> 121.14.154.93:53, proto: 17, zone: 0");
+ EXPECT_TRUE(session_get_tuple6_dir(sess) == SESSION_DIR_C2S);
+ EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_ACTIVE);
+ EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_UDP);
+ EXPECT_TRUE(session_get_c2s_bytes(sess) == 74);
+ EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
+ EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
+ EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
+ EXPECT_TRUE(session_get0_c2s_1st_md(sess) == NULL);
+ EXPECT_TRUE(session_get0_s2c_1st_md(sess) == NULL);
+ EXPECT_TRUE(session_get_create_time(sess) != 0);
+ EXPECT_TRUE(session_get_last_time(sess) != 0);
+ EXPECT_TRUE(session_get_create_time(sess) == session_get_last_time(sess));
+ EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
+ EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
+ EXPECT_TRUE((uint64_t)session_get0_ex_data(sess, udp_builtin_ex) == UDP_C2S_RECVED);
+
+ // check session manager info
+ EXPECT_TRUE(session_manager_get_tcp_opening_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_tcp_closing_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_tcp_active_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_opening_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_closing_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_active_sess_num(mgr) == 1);
+
+ for (int i = 0; i < 4; i++)
+ {
+ timestamp_update();
+ session_manager_dispatch(mgr);
+ sleep(1);
+ }
+
+ // check sess mgr
+ EXPECT_TRUE(session_manager_get_tcp_opening_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_tcp_closing_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_tcp_active_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_opening_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_closing_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_active_sess_num(mgr) == 0);
+
+ // destory
+ session_manager_destroy(mgr);
+}
+#endif
+
+#if 1
+TEST(SESSION_MANAGER, INIT_TO_ACTIVE_BY_UDP_S2C)
+{
+ char buffer[1024];
+ uint64_t max_session_num = 16;
+ struct packet pkt;
+ struct session *sess = NULL;
+ struct session_manager *mgr = NULL;
+
+ timestamp_update();
+ plugin_init();
+
+ mgr = session_manager_create(max_session_num);
+ EXPECT_TRUE(mgr != NULL);
+ session_manager_set_session_eventcb(mgr, plugin_dispatch, (void *)plugin_ctx);
+ session_manager_set_packet_timeout(mgr, 1000);
+ session_manager_set_closing_timeout(mgr, 2000);
+
+ packet_parse(&pkt, (const char *)udp_pkt2_dns_resp, sizeof(udp_pkt2_dns_resp));
+ sess = session_manager_find_session(mgr, &pkt);
+ EXPECT_TRUE(sess);
+
+ // check session info
+ EXPECT_TRUE(session_get_id(sess) == 0);
+ memset(buffer, 0, sizeof(buffer));
+ tuple6_tostring(session_get0_tuple6(sess), buffer, sizeof(buffer));
+ EXPECT_STREQ(buffer, "121.14.154.93:53 -> 192.168.38.105:61099, proto: 17, zone: 0");
+ EXPECT_TRUE(session_get_tuple6_dir(sess) == SESSION_DIR_S2C);
+ EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_ACTIVE);
+ EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_UDP);
+ EXPECT_TRUE(session_get_c2s_bytes(sess) == 0);
+ EXPECT_TRUE(session_get_s2c_bytes(sess) == 550);
+ EXPECT_TRUE(session_get_c2s_packets(sess) == 0);
+ EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
+ EXPECT_TRUE(session_get0_c2s_1st_md(sess) == NULL);
+ EXPECT_TRUE(session_get0_s2c_1st_md(sess) == NULL);
+ EXPECT_TRUE(session_get_create_time(sess) != 0);
+ EXPECT_TRUE(session_get_last_time(sess) != 0);
+ EXPECT_TRUE(session_get_create_time(sess) == session_get_last_time(sess));
+ EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
+ EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
+ EXPECT_TRUE((uint64_t)session_get0_ex_data(sess, udp_builtin_ex) == UDP_S2C_RECVED);
+
+ // check session manager info
+ EXPECT_TRUE(session_manager_get_tcp_opening_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_tcp_closing_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_tcp_active_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_opening_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_closing_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_active_sess_num(mgr) == 1);
+
+ for (int i = 0; i < 4; i++)
+ {
+ timestamp_update();
+ session_manager_dispatch(mgr);
+ sleep(1);
+ }
+
+ // check sess mgr
+ EXPECT_TRUE(session_manager_get_tcp_opening_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_tcp_closing_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_tcp_active_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_opening_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_closing_sess_num(mgr) == 0);
+ EXPECT_TRUE(session_manager_get_udp_active_sess_num(mgr) == 0);
+
+ // destory
+ session_manager_destroy(mgr);
+}
+#endif
+
+TEST(SESSION_MANAGER, OPENING_TO_ACTIVE_BY_TCP_PAYLOAD)
+{
+}
+
+TEST(SESSION_MANAGER, ACTIVE_TO_CLOSING_BY_2_TCP_FINS)
+{
+}
+
+TEST(SESSION_MANAGER, ACTIVE_TO_CLOSING_BY_TCP_RST)
+{
+}
+
+TEST(SESSION_MANAGER, ACTIVE_TO_CLOSING_BY_TCP_TIMEOUT)
+{
+}
+
+TEST(SESSION_MANAGER, ACTIVE_TO_CLOSING_BY_UDP_TIMEOUT)
+{
+}
+
+TEST(SESSION_MANAGER, OPENING_TO_CLOSING_BY_TCP_TIMEOUT)
+{
+}
+
+TEST(SESSION_MANAGER, OPENING_TO_CLOSING_BY_UDP_TIMEOUT)
+{
+}
+
+TEST(SESSION_MANAGER, CLOSING_TO_CLOSED_BY_TCP_TIMEOUT)
+{
+}
+
+TEST(SESSION_MANAGER, CLOSING_TO_CLOSED_BY_UDP_TIMEOUT)
+{
+}
+
+TEST(SESSION_MANAGER, TABLE_FULL_DISCARD)
+{
+}
+
+TEST(SESSION_MANAGER, TCP_FULL_STREAM)
+{
+}
+
+TEST(SESSION_MANAGER, UDP_FULL_STREAM)
+{
+}
+
+// opening -> closing : self protect
+// opening -> closed
+
+int main(int argc, char **argv)
+{
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/src/session/gtest_session_queue.cpp b/src/session/gtest_session_queue.cpp
new file mode 100644
index 0000000..f9223ce
--- /dev/null
+++ b/src/session/gtest_session_queue.cpp
@@ -0,0 +1,29 @@
+#include <gtest/gtest.h>
+
+#include "session_private.h"
+#include "session_queue.h"
+
+TEST(SESSION_QUEUE, POP_PUSH)
+{
+ struct session sess1;
+ struct session sess2;
+ struct session_queue *queue = NULL;
+
+ queue = session_queue_create();
+ EXPECT_TRUE(queue != NULL);
+
+ EXPECT_TRUE(session_queue_pop(queue) == NULL);
+ session_queue_push(queue, &sess1);
+ session_queue_push(queue, &sess2);
+ EXPECT_TRUE(session_queue_pop(queue) == &sess1);
+ EXPECT_TRUE(session_queue_pop(queue) == &sess2);
+ EXPECT_TRUE(session_queue_pop(queue) == NULL);
+
+ session_queue_destroy(queue);
+}
+
+int main(int argc, char **argv)
+{
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/src/session/gtest_session_table.cpp b/src/session/gtest_session_table.cpp
index 1ffcbda..c089f34 100644
--- a/src/session/gtest_session_table.cpp
+++ b/src/session/gtest_session_table.cpp
@@ -147,46 +147,46 @@ TEST(SESSION_TABLE, FIND_OLDEST_NEWEST)
// Add Session
- EXPECT_TRUE(session_table_find_oldest_session(sess_table) == NULL);
- EXPECT_TRUE(session_table_find_newest_session(sess_table) == NULL);
+ EXPECT_TRUE(session_table_find_least_recently_unused_session(sess_table) == NULL);
+ EXPECT_TRUE(session_table_find_least_recently_used_session(sess_table) == NULL);
sess1 = session_pool_alloc(sess_pool);
EXPECT_TRUE(sess1 != NULL);
session_set_id(sess1, 1);
session_set_tuple6(sess1, &tuple_1);
EXPECT_TRUE(session_table_add_session(sess_table, &tuple_1, sess1) == 0);
- EXPECT_TRUE(session_table_find_oldest_session(sess_table) == sess1);
- EXPECT_TRUE(session_table_find_newest_session(sess_table) == sess1);
+ EXPECT_TRUE(session_table_find_least_recently_unused_session(sess_table) == sess1);
+ EXPECT_TRUE(session_table_find_least_recently_used_session(sess_table) == sess1);
sess2 = session_pool_alloc(sess_pool);
EXPECT_TRUE(sess2 != NULL);
session_set_id(sess2, 2);
session_set_tuple6(sess2, &tuple_2);
EXPECT_TRUE(session_table_add_session(sess_table, &tuple_2, sess2) == 0);
- EXPECT_TRUE(session_table_find_oldest_session(sess_table) == sess1);
- EXPECT_TRUE(session_table_find_newest_session(sess_table) == sess2);
+ EXPECT_TRUE(session_table_find_least_recently_unused_session(sess_table) == sess1);
+ EXPECT_TRUE(session_table_find_least_recently_used_session(sess_table) == sess2);
sess3 = session_pool_alloc(sess_pool);
EXPECT_TRUE(sess3 != NULL);
session_set_id(sess3, 3);
session_set_tuple6(sess3, &tuple_3);
EXPECT_TRUE(session_table_add_session(sess_table, &tuple_3, sess3) == 0);
- EXPECT_TRUE(session_table_find_oldest_session(sess_table) == sess1);
- EXPECT_TRUE(session_table_find_newest_session(sess_table) == sess3);
+ EXPECT_TRUE(session_table_find_least_recently_unused_session(sess_table) == sess1);
+ EXPECT_TRUE(session_table_find_least_recently_used_session(sess_table) == sess3);
// Delete Session
session_table_delete_session(sess_table, &tuple_1);
- EXPECT_TRUE(session_table_find_oldest_session(sess_table) == sess2);
- EXPECT_TRUE(session_table_find_newest_session(sess_table) == sess3);
+ EXPECT_TRUE(session_table_find_least_recently_unused_session(sess_table) == sess2);
+ EXPECT_TRUE(session_table_find_least_recently_used_session(sess_table) == sess3);
session_table_delete_session(sess_table, &tuple_2);
- EXPECT_TRUE(session_table_find_oldest_session(sess_table) == sess3);
- EXPECT_TRUE(session_table_find_newest_session(sess_table) == sess3);
+ EXPECT_TRUE(session_table_find_least_recently_unused_session(sess_table) == sess3);
+ EXPECT_TRUE(session_table_find_least_recently_used_session(sess_table) == sess3);
session_table_delete_session(sess_table, &tuple_3);
- EXPECT_TRUE(session_table_find_oldest_session(sess_table) == NULL);
- EXPECT_TRUE(session_table_find_newest_session(sess_table) == NULL);
+ EXPECT_TRUE(session_table_find_least_recently_unused_session(sess_table) == NULL);
+ EXPECT_TRUE(session_table_find_least_recently_used_session(sess_table) == NULL);
// Destroy
session_table_destroy(sess_table);
diff --git a/src/session/session.cpp b/src/session/session.cpp
index 0fbd434..248ef25 100644
--- a/src/session/session.cpp
+++ b/src/session/session.cpp
@@ -18,6 +18,8 @@ struct ex_manager
};
static struct ex_manager g_ex_manager = {0};
+uint8_t tcp_builtin_ex = 0; // built-in ex_data index
+uint8_t udp_builtin_ex = 0; // built-in ex_data index
/******************************************************************************
* ev queue
@@ -81,7 +83,7 @@ void session_set_id(struct session *sess, uint64_t id)
sess->id = id;
}
-uint64_t session_get_id(struct session *sess)
+uint64_t session_get_id(const struct session *sess)
{
return sess->id;
}
@@ -92,18 +94,28 @@ void session_set_tuple6(struct session *sess, struct tuple6 *tuple)
memcpy(&sess->tuple, tuple, sizeof(struct tuple6));
}
-struct tuple6 *session_get0_tuple6(struct session *sess)
+const struct tuple6 *session_get0_tuple6(const struct session *sess)
{
return &sess->tuple;
}
+void session_set_tuple6_dir(struct session *sess, enum session_dir dir)
+{
+ sess->tuple_dir = dir;
+}
+
+enum session_dir session_get_tuple6_dir(const struct session *sess)
+{
+ return sess->tuple_dir;
+}
+
// session state
void session_set_state(struct session *sess, enum session_state state)
{
sess->state = state;
}
-enum session_state session_get_state(struct session *sess)
+enum session_state session_get_state(const struct session *sess)
{
return sess->state;
}
@@ -114,7 +126,7 @@ void session_set_type(struct session *sess, enum session_type type)
sess->type = type;
}
-enum session_type session_get_type(struct session *sess)
+enum session_type session_get_type(const struct session *sess)
{
return sess->type;
}
@@ -132,22 +144,22 @@ void session_inc_s2c_metrics(struct session *sess, uint64_t packets, uint64_t by
sess->s2c_packets += packets;
}
-uint64_t session_get_c2s_bytes(struct session *sess)
+uint64_t session_get_c2s_bytes(const struct session *sess)
{
return sess->c2s_bytes;
}
-uint64_t session_get_s2c_bytes(struct session *sess)
+uint64_t session_get_s2c_bytes(const struct session *sess)
{
return sess->s2c_bytes;
}
-uint64_t session_get_c2s_packets(struct session *sess)
+uint64_t session_get_c2s_packets(const struct session *sess)
{
return sess->c2s_packets;
}
-uint64_t session_get_s2c_packets(struct session *sess)
+uint64_t session_get_s2c_packets(const struct session *sess)
{
return sess->s2c_packets;
}
@@ -163,7 +175,7 @@ void session_set_s2c_1st_md(struct session *sess, struct metadata *md)
memcpy(&sess->s2c_1st_md, md, sizeof(struct metadata));
}
-struct metadata *session_get0_c2s_1st_md(struct session *sess)
+const struct metadata *session_get0_c2s_1st_md(const struct session *sess)
{
if (sess->c2s_1st_md.len == 0)
{
@@ -172,7 +184,7 @@ struct metadata *session_get0_c2s_1st_md(struct session *sess)
return &sess->c2s_1st_md;
}
-struct metadata *session_get0_s2c_1st_md(struct session *sess)
+const struct metadata *session_get0_s2c_1st_md(const struct session *sess)
{
if (sess->s2c_1st_md.len == 0)
{
@@ -192,12 +204,12 @@ void session_set_last_time(struct session *sess, uint64_t timestamp)
sess->last_time = timestamp;
}
-uint64_t session_get_create_time(struct session *sess)
+uint64_t session_get_create_time(const struct session *sess)
{
return sess->create_time;
}
-uint64_t session_get_last_time(struct session *sess)
+uint64_t session_get_last_time(const struct session *sess)
{
return sess->last_time;
}
@@ -212,7 +224,7 @@ void session_set0_cur_pkt(struct session *sess, const struct packet *pkt)
sess->cur_pkt = pkt;
}
-const struct packet *session_get0_cur_pkt(struct session *sess)
+const struct packet *session_get0_cur_pkt(const struct session *sess)
{
return sess->cur_pkt;
}
@@ -223,7 +235,7 @@ void session_set_cur_dir(struct session *sess, enum session_dir dir)
sess->cur_dir = dir;
}
-enum session_dir session_get_cur_dir(struct session *sess)
+enum session_dir session_get_cur_dir(const struct session *sess)
{
return sess->cur_dir;
}
@@ -301,7 +313,7 @@ void session_set_ex_data(struct session *sess, uint8_t idx, void *val)
sess->ex_data[idx] = val;
}
-void *session_get0_ex_data(struct session *sess, uint8_t idx)
+void *session_get0_ex_data(const struct session *sess, uint8_t idx)
{
if (idx >= g_ex_manager.count)
{
@@ -365,4 +377,193 @@ void session_run_expirecb(struct session *sess)
{
sess->expire_cb(sess, sess->expire_arg);
}
+}
+
+/******************************************************************************
+ * session dump
+ ******************************************************************************/
+
+static void tcp_ex_data_tostring(uint64_t ex_data, char *buffer, size_t buffer_len)
+{
+ if (ex_data == 0)
+ {
+ return;
+ }
+
+ int nused = 0;
+ if (ex_data & TCP_SYN_RECVED)
+ {
+ snprintf(buffer + nused, buffer_len - nused, "TCP_SYN_RECVED ");
+ }
+
+ if (ex_data & TCP_SYNACK_RECVED)
+ {
+ snprintf(buffer + nused, buffer_len - nused, "TCP_SYNACK_RECVED ");
+ }
+
+ if (ex_data & TCP_ACK_RECVED)
+ {
+ snprintf(buffer + nused, buffer_len - nused, "TCP_ACK_RECVED ");
+ }
+
+ if (ex_data & TCP_C2S_PAYLOAD_RECVED)
+ {
+ snprintf(buffer + nused, buffer_len - nused, "TCP_C2S_PAYLOAD_RECVED ");
+ }
+
+ if (ex_data & TCP_S2C_PAYLOAD_RECVED)
+ {
+ snprintf(buffer + nused, buffer_len - nused, "TCP_S2C_PAYLOAD_RECVED ");
+ }
+
+ if (ex_data & TCP_C2S_FIN_RECVED)
+ {
+ snprintf(buffer + nused, buffer_len - nused, "TCP_C2S_FIN_RECVED ");
+ }
+
+ if (ex_data & TCP_S2C_FIN_RECVED)
+ {
+ snprintf(buffer + nused, buffer_len - nused, "TCP_S2C_FIN_RECVED ");
+ }
+
+ if (ex_data & TCP_C2S_RST_RECVED)
+ {
+ snprintf(buffer + nused, buffer_len - nused, "TCP_C2S_RST_RECVED ");
+ }
+
+ if (ex_data & TCP_S2C_RST_RECVED)
+ {
+ snprintf(buffer + nused, buffer_len - nused, "TCP_S2C_RST_RECVED ");
+ }
+}
+
+static void udp_ex_data_tostring(uint64_t ex_data, char *buffer, size_t buffer_len)
+{
+ if (ex_data == 0)
+ {
+ return;
+ }
+
+ int nused = 0;
+ if (ex_data & UDP_C2S_RECVED)
+ {
+ snprintf(buffer + nused, buffer_len - nused, "UDP_C2S_RECVED ");
+ }
+
+ if (ex_data & UDP_S2C_RECVED)
+ {
+ snprintf(buffer + nused, buffer_len - nused, "UDP_S2C_RECVED ");
+ }
+}
+
+const char *session_event_tostring(enum session_event event)
+{
+ switch (event)
+ {
+ case SESSION_EVENT_NONE:
+ return "none";
+ case SESSION_EVENT_OPENING:
+ return "opening";
+ case SESSION_EVENT_ACTIVE:
+ return "active";
+ case SESSION_EVENT_CLOSING:
+ return "closing";
+ default:
+ return "unknown";
+ }
+}
+
+const char *session_state_tostring(enum session_state state)
+{
+ switch (state)
+ {
+ case SESSION_STATE_INIT:
+ return "init";
+ case SESSION_STATE_OPENING:
+ return "opening";
+ case SESSION_STATE_ACTIVE:
+ return "active";
+ case SESSION_STATE_DISCARD:
+ return "discard";
+ case SESSION_STATE_CLOSING:
+ return "closing";
+ case SESSION_STATE_CLOSED:
+ return "closed";
+ default:
+ return "unknown";
+ }
+}
+
+const char *session_type_tostring(enum session_type type)
+{
+ switch (type)
+ {
+ case SESSION_TYPE_NONE:
+ return "none";
+ case SESSION_TYPE_TCP:
+ return "tcp";
+ case SESSION_TYPE_TCP_STREAM:
+ return "tcp_stream";
+ case SESSION_TYPE_UDP:
+ return "udp";
+ default:
+ return "unknown";
+ }
+}
+
+const char *session_dir_tostring(enum session_dir dir)
+{
+ switch (dir)
+ {
+ case SESSION_DIR_NONE:
+ return "none";
+ case SESSION_DIR_C2S:
+ return "c2s";
+ case SESSION_DIR_S2C:
+ return "s2c";
+ default:
+ return "unknown";
+ }
+}
+
+void session_dump(struct session *sess)
+{
+ char buffer[128] = {0};
+ tuple6_tostring(session_get0_tuple6(sess), buffer, sizeof(buffer));
+
+ printf("session id : %" PRIu64 "\n", session_get_id(sess));
+ printf("session tuple6 : %s\n", buffer);
+ printf("session tuple6 dir : %s\n", session_dir_tostring(session_get_tuple6_dir(sess)));
+ printf("session state : %s\n", session_state_tostring(session_get_state(sess)));
+ printf("session type : %s\n", session_type_tostring(session_get_type(sess)));
+ printf("session c2s packets : %" PRIu64 "\n", session_get_c2s_packets(sess));
+ printf("session c2s bytes : %" PRIu64 "\n", session_get_c2s_bytes(sess));
+ printf("session s2c packets : %" PRIu64 "\n", session_get_s2c_packets(sess));
+ printf("session s2c bytes : %" PRIu64 "\n", session_get_s2c_bytes(sess));
+ printf("session c2s 1st metadata : %p\n", (void *)session_get0_c2s_1st_md(sess));
+ printf("session s2c 1st metadata : %p\n", (void *)session_get0_s2c_1st_md(sess));
+ printf("session create time : %" PRIu64 "\n", session_get_create_time(sess));
+ printf("session last time : %" PRIu64 "\n", session_get_last_time(sess));
+ printf("session current packet : %p\n", (void *)session_get0_cur_pkt(sess));
+ printf("session current dir : %s\n", session_dir_tostring(session_get_cur_dir(sess)));
+ printf("session ex data: \n");
+ for (uint8_t i = 0; i < g_ex_manager.count; i++)
+ {
+ if (i == tcp_builtin_ex)
+ {
+ memset(buffer, 0, sizeof(buffer));
+ tcp_ex_data_tostring((uint64_t)sess->ex_data[i], buffer, sizeof(buffer));
+ printf(" ex_idx: %d, ex_key: %s, ex_val: %s\n", i, g_ex_manager.schemas[i].key, buffer);
+ }
+ else if (i == udp_builtin_ex)
+ {
+ memset(buffer, 0, sizeof(buffer));
+ udp_ex_data_tostring((uint64_t)sess->ex_data[i], buffer, sizeof(buffer));
+ printf(" ex_idx: %d, ex_key: %s, ex_val: %s\n", i, g_ex_manager.schemas[i].key, buffer);
+ }
+ else
+ {
+ printf(" ex_idx: %d, ex_key: %s, ex_val: %p\n", i, g_ex_manager.schemas[i].key, sess->ex_data[i]);
+ }
+ }
} \ No newline at end of file
diff --git a/src/session/session.h b/src/session/session.h
index 05798e3..e82a7fd 100644
--- a/src/session/session.h
+++ b/src/session/session.h
@@ -9,6 +9,7 @@ extern "C"
#include <stdint.h>
#include "tuple.h"
+#include "packet.h"
enum session_state
{
@@ -42,8 +43,9 @@ enum session_event
enum session_dir
{
- SESSION_DIR_C2S = 0,
- SESSION_DIR_S2C = 1,
+ SESSION_DIR_NONE = 0,
+ SESSION_DIR_C2S = 1,
+ SESSION_DIR_S2C = 2,
};
struct metadata
@@ -62,39 +64,41 @@ void session_init(struct session *sess);
// session id
void session_set_id(struct session *sess, uint64_t id);
-uint64_t session_get_id(struct session *sess);
+uint64_t session_get_id(const struct session *sess);
// session key
void session_set_tuple6(struct session *sess, struct tuple6 *tuple);
-struct tuple6 *session_get0_tuple6(struct session *sess);
+const struct tuple6 *session_get0_tuple6(const struct session *sess);
+void session_set_tuple6_dir(struct session *sess, enum session_dir dir);
+enum session_dir session_get_tuple6_dir(const struct session *sess);
// session state
void session_set_state(struct session *sess, enum session_state state);
-enum session_state session_get_state(struct session *sess);
+enum session_state session_get_state(const struct session *sess);
// session type
void session_set_type(struct session *sess, enum session_type type);
-enum session_type session_get_type(struct session *sess);
+enum session_type session_get_type(const struct session *sess);
// session metrics
void session_inc_c2s_metrics(struct session *sess, uint64_t packets, uint64_t bytes);
void session_inc_s2c_metrics(struct session *sess, uint64_t packets, uint64_t bytes);
-uint64_t session_get_c2s_bytes(struct session *sess);
-uint64_t session_get_s2c_bytes(struct session *sess);
-uint64_t session_get_c2s_packets(struct session *sess);
-uint64_t session_get_s2c_packets(struct session *sess);
+uint64_t session_get_c2s_bytes(const struct session *sess);
+uint64_t session_get_s2c_bytes(const struct session *sess);
+uint64_t session_get_c2s_packets(const struct session *sess);
+uint64_t session_get_s2c_packets(const struct session *sess);
// session metadata
void session_set_c2s_1st_md(struct session *sess, struct metadata *md);
void session_set_s2c_1st_md(struct session *sess, struct metadata *md);
-struct metadata *session_get0_c2s_1st_md(struct session *sess);
-struct metadata *session_get0_s2c_1st_md(struct session *sess);
+const struct metadata *session_get0_c2s_1st_md(const struct session *sess);
+const struct metadata *session_get0_s2c_1st_md(const struct session *sess);
// session timestamp
void session_set_create_time(struct session *sess, uint64_t timestamp);
void session_set_last_time(struct session *sess, uint64_t timestamp);
-uint64_t session_get_create_time(struct session *sess);
-uint64_t session_get_last_time(struct session *sess);
+uint64_t session_get_create_time(const struct session *sess);
+uint64_t session_get_last_time(const struct session *sess);
/******************************************************************************
* session current packet
@@ -102,11 +106,11 @@ uint64_t session_get_last_time(struct session *sess);
// session current packet
void session_set0_cur_pkt(struct session *sess, const struct packet *pkt);
-const struct packet *session_get0_cur_pkt(struct session *sess);
+const struct packet *session_get0_cur_pkt(const struct session *sess);
// session current dir
void session_set_cur_dir(struct session *sess, enum session_dir dir);
-enum session_dir session_get_cur_dir(struct session *sess);
+enum session_dir session_get_cur_dir(const struct session *sess);
/******************************************************************************
* session event
@@ -139,7 +143,7 @@ uint8_t session_get_ex_new_index(const char *key, session_ex_free_cb *free_cb, v
* if key not exist: set new value.
*/
void session_set_ex_data(struct session *sess, uint8_t idx, void *val);
-void *session_get0_ex_data(struct session *sess, uint8_t idx);
+void *session_get0_ex_data(const struct session *sess, uint8_t idx);
/*
* after set ex_data, the owner of ex_data is session, so user should not free it directly.
* if user want to free ex_data, should use session_free_ex_data.
@@ -157,6 +161,16 @@ void session_set_expirecb(struct session *sess, session_expire_cb expire_cb, voi
void session_del_expirecb(struct session *sess);
void session_run_expirecb(struct session *sess);
+/******************************************************************************
+ * session dump
+ ******************************************************************************/
+
+const char *session_event_tostring(enum session_event event);
+const char *session_state_tostring(enum session_state state);
+const char *session_type_tostring(enum session_type type);
+const char *session_dir_tostring(enum session_dir dir);
+void session_dump(struct session *sess);
+
#ifdef __cpluscplus
}
#endif
diff --git a/src/session/session_manager.cpp b/src/session/session_manager.cpp
index 03f51a4..336c877 100644
--- a/src/session/session_manager.cpp
+++ b/src/session/session_manager.cpp
@@ -6,108 +6,505 @@
#include "session_pool.h"
#include "session_table.h"
#include "session_timer.h"
+#include "session_queue.h"
#include "session_private.h"
+#include "packet_helpers.h"
struct session_manager
{
struct session_pool *sess_pool;
struct session_table *sess_table;
struct session_timer *sess_timer;
+ struct session_queue *sess_queue; // ready session queue
session_event_cb event_cb;
void *arg;
- struct session *queue_head_ptr;
- struct session *queue_tail_ptr;
+ // timeout config
+ uint64_t packet_timeout_ms;
+ uint64_t closing_timeout_ms;
+
+ // session number
+ uint64_t tcp_opening_sess_num;
+ uint64_t tcp_closing_sess_num;
+ uint64_t tcp_active_sess_num;
+
+ uint64_t udp_opening_sess_num;
+ uint64_t udp_closing_sess_num;
+ uint64_t udp_active_sess_num;
};
-#define HANDSHAKE_TIMEOUT_MS (5 * 1000)
-#define DATA_TIMEOUT_MS (60 * 1000)
+/******************************************************************************
+ * utils
+ ******************************************************************************/
+
+// TODO
+static uint64_t alloc_session_id(void)
+{
+ return 0;
+}
+
+// TODO
+struct metadata *packet_get0_metadata(const struct packet *pkt)
+{
+ static struct metadata md = {0};
+ return &md;
+};
/******************************************************************************
- * private API
+ * session manager counter
******************************************************************************/
-static void session_manager_handle_new_session(struct session_manager *mgr, struct session_key *key, struct session *sess, const struct packet *pkt)
+static void update_counter_on_opening(struct session_manager *mgr, struct session *sess)
{
- // TODO
+ if (session_get_state(sess) == SESSION_STATE_INIT)
+ {
+ if (session_get_type(sess) == SESSION_TYPE_TCP)
+ {
+ mgr->tcp_opening_sess_num++;
+ }
+ else
+ {
+ mgr->udp_opening_sess_num++;
+ }
+ }
}
-static void session_manager_handle_old_session(struct session_manager *mgr, struct session_key *key, struct session *sess, const struct packet *pkt)
+static void update_counter_on_active(struct session_manager *mgr, struct session *sess)
{
- // TODO
+ if (session_get_state(sess) == SESSION_STATE_OPENING)
+ {
+ if (session_get_type(sess) == SESSION_TYPE_TCP)
+ {
+ mgr->tcp_opening_sess_num--;
+ mgr->tcp_active_sess_num++;
+ }
+ else
+ {
+ mgr->udp_opening_sess_num--;
+ mgr->udp_active_sess_num++;
+ }
+ }
}
-// Enqueue ready session to queue tail
-static void session_manager_enqueue_ready_session(struct session_manager *mgr, struct session *sess)
+static void update_counter_on_closing(struct session_manager *mgr, struct session *sess)
{
- if (mgr == NULL || sess == NULL)
+ if (session_get_state(sess) == SESSION_STATE_OPENING)
{
+ if (session_get_type(sess) == SESSION_TYPE_TCP)
+ {
+ mgr->tcp_opening_sess_num--;
+ mgr->tcp_closing_sess_num++;
+ }
+ else
+ {
+ mgr->udp_opening_sess_num--;
+ mgr->udp_closing_sess_num++;
+ }
+
return;
}
- if (mgr->queue_head_ptr == NULL)
+ if (session_get_state(sess) == SESSION_STATE_ACTIVE)
{
- mgr->queue_head_ptr = sess;
- mgr->queue_tail_ptr = sess;
- sess->next_ready_ptr = NULL;
+ if (session_get_type(sess) == SESSION_TYPE_TCP)
+ {
+ mgr->tcp_active_sess_num--;
+ mgr->tcp_closing_sess_num++;
+ }
+ else
+ {
+ mgr->udp_active_sess_num--;
+ mgr->udp_closing_sess_num++;
+ }
+
+ return;
}
- else
+}
+
+static void update_counter_on_closed(struct session_manager *mgr, struct session *sess)
+{
+ if (session_get_state(sess) == SESSION_STATE_CLOSING)
{
- mgr->queue_tail_ptr->next_ready_ptr = sess;
- mgr->queue_tail_ptr = sess;
- sess->next_ready_ptr = NULL;
+ if (session_get_type(sess) == SESSION_TYPE_TCP)
+ {
+ mgr->tcp_closing_sess_num--;
+ }
+ else
+ {
+ mgr->udp_closing_sess_num--;
+ }
}
}
-// Dequeue ready session from queue head
-struct session *session_manager_ready_session_dequeue(struct session_manager *mgr)
+/******************************************************************************
+ * judge session direction
+ ******************************************************************************/
+
+static enum session_dir judge_direction_by_tuple6(const struct tuple6 *key)
{
- if (mgr == NULL)
+ // big port is client
+ if (ntohs(key->src_port) > ntohs(key->dst_port))
{
- return NULL;
+ return SESSION_DIR_C2S;
}
-
- struct session *sess = mgr->queue_head_ptr;
- if (sess == NULL)
+ else
{
- return NULL;
+ return SESSION_DIR_S2C;
}
+}
- if (mgr->queue_head_ptr == mgr->queue_tail_ptr)
+static enum session_dir judge_direction_by_session(const struct session *sess, const struct tuple6 *key)
+{
+ if (tuple6_cmp(session_get0_tuple6(sess), key) == 0)
{
- mgr->queue_head_ptr = NULL;
- mgr->queue_tail_ptr = NULL;
+ return session_get_tuple6_dir(sess);
}
else
{
- mgr->queue_head_ptr = sess->next_ready_ptr;
+ if (session_get_tuple6_dir(sess) == SESSION_DIR_C2S)
+ {
+ return SESSION_DIR_S2C;
+ }
+ else
+ {
+ return SESSION_DIR_C2S;
+ }
}
+}
- sess->next_ready_ptr = NULL;
- return sess;
+/******************************************************************************
+ * update session event and timer
+ ******************************************************************************/
+
+void session_manager_trigger_session_event(struct session_manager *mgr, struct session *sess, uint32_t event)
+{
+ session_push_event(sess, event);
+ session_queue_push(mgr->sess_queue, sess);
}
-// handshake expire set to discard
-static void handshake_expire_cb(struct session *sess, void *arg)
+void session_manager_update_session_timer(struct session_manager *mgr, struct session *sess, session_expire_cb cb, uint64_t timeout_ms)
{
+ session_timer_del_session(mgr->sess_timer, sess);
+ session_set_expirecb(sess, cb, mgr, timestamp_get_msec() + timeout_ms);
+ session_timer_add_session(mgr->sess_timer, sess);
+}
+
+/******************************************************************************
+ * expire callback
+ ******************************************************************************/
+
+static void closing_expire_callback(struct session *sess, void *arg)
+{
+ SESSION_MANAGER_LOG_DEBUG("session %lu closing expire, free session", session_get_id(sess));
struct session_manager *mgr = (struct session_manager *)arg;
assert(mgr != NULL);
- session_set_state(sess, SESSION_STATE_DISCARD);
- session_push_event(sess, SESSION_EVENT_CLOSING);
- session_manager_enqueue_ready_session(mgr, sess);
+ uint32_t event;
+ while (session_pop_event(sess, &event))
+ {
+ }
+
+ update_counter_on_closed(mgr, sess);
+ session_set_state(sess, SESSION_STATE_CLOSED);
+ session_set0_cur_pkt(sess, NULL);
+ session_set_cur_dir(sess, SESSION_DIR_NONE);
+ for (uint8_t i = 0; i < EX_DATA_MAX_COUNT; i++)
+ {
+ session_free_ex_data(sess, i);
+ }
+ session_table_delete_session(mgr->sess_table, session_get0_tuple6(sess));
+ session_timer_del_session(mgr->sess_timer, sess);
+ session_pool_free(mgr->sess_pool, sess);
}
-// data expire set to closing
-static void data_expire_cb(struct session *sess, void *arg)
+static void packet_expire_callback(struct session *sess, void *arg)
{
+ SESSION_MANAGER_LOG_DEBUG("session %lu packet expire, trigger closing event", session_get_id(sess));
struct session_manager *mgr = (struct session_manager *)arg;
assert(mgr != NULL);
+ update_counter_on_closing(mgr, sess);
session_set_state(sess, SESSION_STATE_CLOSING);
- session_push_event(sess, SESSION_EVENT_CLOSING);
- session_manager_enqueue_ready_session(mgr, sess);
+ session_manager_trigger_session_event(mgr, sess, SESSION_EVENT_CLOSING);
+ session_manager_update_session_timer(mgr, sess, closing_expire_callback, mgr->closing_timeout_ms);
+}
+
+/******************************************************************************
+ * session ex data
+ ******************************************************************************/
+
+static int tcp_need_closing(uint64_t state)
+{
+ if ((state & TCP_C2S_FIN_RECVED) && (state & TCP_S2C_FIN_RECVED))
+ {
+ return 1;
+ }
+
+ if (state & TCP_C2S_RST_RECVED)
+ {
+ return 1;
+ }
+
+ if (state & TCP_S2C_RST_RECVED)
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+static int tcp_need_active(uint64_t state)
+{
+ if ((state & TCP_C2S_PAYLOAD_RECVED) || (state & TCP_S2C_PAYLOAD_RECVED))
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+static void update_session_base(struct session *sess, const struct packet *pkt, enum session_dir curr_dir)
+{
+ uint64_t len = packet_get_raw_len(pkt);
+ struct metadata *md = packet_get0_metadata(pkt);
+ if (curr_dir == SESSION_DIR_C2S)
+ {
+ session_inc_c2s_metrics(sess, 1, len);
+ if (session_get0_c2s_1st_md(sess) == NULL)
+ {
+ session_set_c2s_1st_md(sess, md);
+ }
+ }
+ else
+ {
+ session_inc_s2c_metrics(sess, 1, len);
+ if (session_get0_s2c_1st_md(sess) == NULL)
+ {
+ session_set_s2c_1st_md(sess, md);
+ }
+ }
+ session_set_last_time(sess, timestamp_get_msec());
+ session_set0_cur_pkt(sess, pkt);
+ session_set_cur_dir(sess, curr_dir);
+}
+
+static void update_tcp_ex_data(struct session *sess, const struct packet *pkt, enum session_dir curr_dir)
+{
+ uint64_t state = (uint64_t)session_get0_ex_data(sess, tcp_builtin_ex);
+ if (packet_has_tcp_flag_rst(pkt))
+ {
+ if (curr_dir == SESSION_DIR_C2S)
+ {
+ session_set_ex_data(sess, tcp_builtin_ex, (void *)(state & TCP_C2S_RST_RECVED));
+ }
+ else
+ {
+ session_set_ex_data(sess, tcp_builtin_ex, (void *)(state & TCP_S2C_RST_RECVED));
+ }
+ }
+
+ if (packet_has_tcp_flag_fin(pkt))
+ {
+ if (curr_dir == SESSION_DIR_C2S)
+ {
+ session_set_ex_data(sess, tcp_builtin_ex, (void *)(state & TCP_C2S_FIN_RECVED));
+ }
+ else
+ {
+ session_set_ex_data(sess, tcp_builtin_ex, (void *)(state & TCP_S2C_FIN_RECVED));
+ }
+ }
+
+ if (packet_has_tcp_flag_syn(pkt))
+ {
+ if (packet_has_tcp_flag_ack(pkt))
+ {
+ session_set_ex_data(sess, tcp_builtin_ex, (void *)(state | TCP_SYNACK_RECVED));
+ }
+ else
+ {
+ session_set_ex_data(sess, tcp_builtin_ex, (void *)(state | TCP_SYN_RECVED));
+ }
+ }
+
+ if (packet_has_tcp_flag_ack(pkt) && curr_dir == SESSION_DIR_C2S)
+ {
+ session_set_ex_data(sess, tcp_builtin_ex, (void *)(state | TCP_ACK_RECVED));
+ }
+
+ if (packet_get_tcp_pld_len(pkt) > 0)
+ {
+ if (curr_dir == SESSION_DIR_C2S)
+ {
+ session_set_ex_data(sess, tcp_builtin_ex, (void *)(state | TCP_C2S_PAYLOAD_RECVED));
+ }
+ else
+ {
+ session_set_ex_data(sess, tcp_builtin_ex, (void *)(state | TCP_S2C_PAYLOAD_RECVED));
+ }
+ }
+}
+
+static void update_udp_ex_data(struct session *sess, const struct packet *pkt, enum session_dir curr_dir)
+{
+ uint64_t state = (uint64_t)session_get0_ex_data(sess, udp_builtin_ex);
+ if (curr_dir == SESSION_DIR_C2S)
+ {
+ session_set_ex_data(sess, udp_builtin_ex, (void *)(state | UDP_C2S_RECVED));
+ }
+ else
+ {
+ session_set_ex_data(sess, udp_builtin_ex, (void *)(state | UDP_S2C_RECVED));
+ }
+}
+
+/******************************************************************************
+ * handle session
+ ******************************************************************************/
+
+// return 0: success
+// return -1: tcp not syn packet, discard
+static int handle_tcp_new_session(struct session_manager *mgr, struct tuple6 *key, struct session *sess, const struct packet *pkt)
+{
+ if (!packet_has_tcp_flag_syn(pkt))
+ {
+ // not syn packet, discard
+ return -1;
+ }
+
+ enum session_dir curr_dir = SESSION_DIR_NONE;
+
+ session_init(sess);
+ // syn packet
+ if (!packet_has_tcp_flag_ack(pkt))
+ {
+ curr_dir = SESSION_DIR_C2S;
+ session_set_ex_data(sess, tcp_builtin_ex, (void *)TCP_SYN_RECVED);
+ }
+ // syn ack packet
+ else
+ {
+ curr_dir = SESSION_DIR_S2C;
+ session_set_ex_data(sess, tcp_builtin_ex, (void *)TCP_SYNACK_RECVED);
+ }
+
+ session_set_id(sess, alloc_session_id());
+ session_set_tuple6(sess, key);
+ session_set_tuple6_dir(sess, curr_dir);
+
+ session_set_type(sess, SESSION_TYPE_TCP);
+ update_counter_on_opening(mgr, sess);
+ session_set_state(sess, SESSION_STATE_OPENING);
+
+ session_set_create_time(sess, timestamp_get_msec());
+ update_session_base(sess, pkt, curr_dir);
+
+ session_manager_trigger_session_event(mgr, sess, SESSION_EVENT_OPENING);
+ session_manager_update_session_timer(mgr, sess, packet_expire_callback, mgr->packet_timeout_ms);
+
+ return 0;
+}
+
+// always return 0
+static int handle_udp_new_session(struct session_manager *mgr, struct tuple6 *key, struct session *sess, const struct packet *pkt)
+{
+ enum session_dir curr_dir = judge_direction_by_tuple6(key);
+
+ session_init(sess);
+ update_udp_ex_data(sess, pkt, curr_dir);
+ session_set_id(sess, alloc_session_id());
+ session_set_tuple6(sess, key);
+ session_set_tuple6_dir(sess, curr_dir);
+
+ /*
+ * when a UDP Session is created, the Opening and active events are triggered,
+ * (the plugin is called twice by the opening/active events in turn),
+ * and the state of the UDP session is directly switched to the active state.
+ */
+ session_set_type(sess, SESSION_TYPE_UDP);
+ update_counter_on_opening(mgr, sess);
+ session_set_state(sess, SESSION_STATE_OPENING);
+ update_counter_on_active(mgr, sess);
+ session_set_state(sess, SESSION_STATE_ACTIVE);
+
+ session_set_create_time(sess, timestamp_get_msec());
+ update_session_base(sess, pkt, curr_dir);
+
+ session_manager_trigger_session_event(mgr, sess, SESSION_EVENT_OPENING);
+ session_manager_trigger_session_event(mgr, sess, SESSION_EVENT_ACTIVE);
+ session_manager_update_session_timer(mgr, sess, packet_expire_callback, mgr->packet_timeout_ms);
+
+ return 0;
+}
+
+static void handle_tcp_old_session(struct session_manager *mgr, struct tuple6 *key, struct session *sess, const struct packet *pkt)
+{
+ enum session_dir curr_dir = judge_direction_by_session(sess, key);
+ update_tcp_ex_data(sess, pkt, curr_dir);
+ update_session_base(sess, pkt, curr_dir);
+
+ uint64_t state = (uint64_t)session_get0_ex_data(sess, tcp_builtin_ex);
+ if (tcp_need_closing(state))
+ {
+ update_counter_on_closing(mgr, sess);
+ session_set_state(sess, SESSION_STATE_CLOSING);
+ session_manager_trigger_session_event(mgr, sess, SESSION_EVENT_CLOSING);
+ session_manager_update_session_timer(mgr, sess, closing_expire_callback, mgr->closing_timeout_ms);
+ return;
+ }
+
+ if (tcp_need_active(state))
+ {
+ update_counter_on_active(mgr, sess);
+ session_set_state(sess, SESSION_STATE_ACTIVE);
+ session_manager_trigger_session_event(mgr, sess, SESSION_EVENT_ACTIVE);
+ session_manager_update_session_timer(mgr, sess, packet_expire_callback, mgr->packet_timeout_ms);
+ return;
+ }
+}
+
+static void handle_udp_old_session(struct session_manager *mgr, struct tuple6 *key, struct session *sess, const struct packet *pkt)
+{
+ enum session_dir curr_dir = judge_direction_by_session(sess, key);
+ update_udp_ex_data(sess, pkt, curr_dir);
+ update_session_base(sess, pkt, curr_dir);
+
+ update_counter_on_active(mgr, sess);
+ session_set_state(sess, SESSION_STATE_ACTIVE);
+ session_manager_trigger_session_event(mgr, sess, SESSION_EVENT_ACTIVE);
+ session_manager_update_session_timer(mgr, sess, packet_expire_callback, mgr->packet_timeout_ms);
+}
+
+// return 0: success
+// return -1: tcp not syn packet, discard
+static int handle_new_session(struct session_manager *mgr, struct tuple6 *key, struct session *sess, const struct packet *pkt)
+{
+ if (packet_has_tcp(pkt))
+ {
+ return handle_tcp_new_session(mgr, key, sess, pkt);
+ }
+ else
+ {
+ return handle_udp_new_session(mgr, key, sess, pkt);
+ }
+}
+
+static void handle_old_session(struct session_manager *mgr, struct tuple6 *key, struct session *sess, const struct packet *pkt)
+{
+ if (session_get_state(sess) == SESSION_STATE_CLOSING)
+ {
+ return;
+ }
+
+ if (packet_has_tcp(pkt))
+ {
+ handle_tcp_old_session(mgr, key, sess, pkt);
+ }
+ else
+ {
+ handle_udp_old_session(mgr, key, sess, pkt);
+ }
}
/******************************************************************************
@@ -140,8 +537,25 @@ struct session_manager *session_manager_create(uint64_t max_session_num)
goto error;
}
- mgr->queue_head_ptr = NULL;
- mgr->queue_tail_ptr = NULL;
+ mgr->sess_queue = session_queue_create();
+ if (mgr->sess_queue == NULL)
+ {
+ goto error;
+ }
+
+ mgr->closing_timeout_ms = 2 * 1000;
+ mgr->packet_timeout_ms = 5 * 1000;
+
+ mgr->tcp_opening_sess_num = 0;
+ mgr->tcp_closing_sess_num = 0;
+ mgr->tcp_active_sess_num = 0;
+
+ mgr->udp_opening_sess_num = 0;
+ mgr->udp_closing_sess_num = 0;
+ mgr->udp_active_sess_num = 0;
+
+ tcp_builtin_ex = session_get_ex_new_index("tcp_builtin_ex", NULL, NULL);
+ udp_builtin_ex = session_get_ex_new_index("udp_builtin_ex", NULL, NULL);
return mgr;
@@ -154,6 +568,7 @@ void session_manager_destroy(struct session_manager *mgr)
{
if (mgr)
{
+ session_queue_destroy(mgr->sess_queue);
session_timer_destroy(mgr->sess_timer);
session_table_destroy(mgr->sess_table);
session_pool_destroy(mgr->sess_pool);
@@ -168,31 +583,60 @@ void session_manager_set_session_eventcb(struct session_manager *mgr, session_ev
mgr->arg = arg;
}
+void session_manager_set_packet_timeout(struct session_manager *mgr, uint64_t timeout_ms)
+{
+ mgr->packet_timeout_ms = timeout_ms;
+}
+
+void session_manager_set_closing_timeout(struct session_manager *mgr, uint64_t timeout_ms)
+{
+ mgr->closing_timeout_ms = timeout_ms;
+}
+
+// return NULL: discard
+// * tuple6 not find
+// * tcp first packet not syn
struct session *session_manager_find_session(struct session_manager *mgr, const struct packet *pkt)
{
- struct session_key key;
- // TODO packet to key
+ struct tuple6 key;
+ if (packet_get_innermost_tuple6(pkt, &key) == -1)
+ {
+ return NULL;
+ }
struct session *sess = session_table_find_session(mgr->sess_table, &key);
if (sess == NULL)
{
+ // if session pool is full, discard oldest session
if (session_pool_get_count(mgr->sess_pool) == 1)
{
- struct session *oldest_sess = session_table_find_oldest_session(mgr->sess_table);
- assert(oldest_sess == NULL);
- session_set_state(oldest_sess, SESSION_STATE_DISCARD);
- session_push_event(oldest_sess, SESSION_EVENT_CLOSING);
- session_manager_enqueue_ready_session(mgr, oldest_sess);
+ struct session *unused_sess = session_table_find_least_recently_unused_session(mgr->sess_table);
+ assert(unused_sess);
+
+ update_counter_on_closing(mgr, unused_sess);
+ session_set_state(unused_sess, SESSION_STATE_DISCARD);
+ session_manager_trigger_session_event(mgr, unused_sess, SESSION_EVENT_CLOSING);
+ session_manager_update_session_timer(mgr, unused_sess, closing_expire_callback, mgr->closing_timeout_ms);
}
sess = session_pool_alloc(mgr->sess_pool);
assert(sess != NULL);
- session_manager_handle_new_session(mgr, &key, sess, pkt);
+ // return 0: success
+ // return -1: tcp not syn packet, discard
+ if (handle_new_session(mgr, &key, sess, pkt) == 0)
+ {
+ session_table_add_session(mgr->sess_table, &key, sess);
+ }
+ else
+ {
+ session_pool_free(mgr->sess_pool, sess);
+ return NULL;
+ }
}
else
{
- session_manager_handle_old_session(mgr, &key, sess, pkt);
+ handle_old_session(mgr, &key, sess, pkt);
}
return sess;
@@ -206,19 +650,24 @@ void session_manager_dispatch(struct session_manager *mgr)
void *cb_arg = mgr->arg;
session_event_cb event_cb = mgr->event_cb;
- while (1)
+ SESSION_MANAGER_LOG_DEBUG("current timestamp: %lu s", timestamp_get_sec());
+
+ // limit expire session number
+ for (int i = 0; i < 100; i++)
{
sess = session_timer_expire_session(mgr->sess_timer, timestamp_get_msec());
if (sess == NULL)
{
break;
}
+
session_run_expirecb(sess);
}
while (1)
{
- sess = session_manager_ready_session_dequeue(mgr);
+ // get session from ready queue
+ sess = session_queue_pop(mgr->sess_queue);
if (sess == NULL)
{
break;
@@ -226,15 +675,49 @@ void session_manager_dispatch(struct session_manager *mgr)
while (1)
{
+ // get event from session
if (session_pop_event(sess, &event) == false)
{
break;
}
+ SESSION_MANAGER_LOG_DEBUG("handle \"%s\" event on session %lu", session_event_tostring((enum session_event)event), session_get_id(sess));
if (event_cb)
{
event_cb(sess, event, cb_arg);
}
}
+ session_set0_cur_pkt(sess, NULL);
+ session_set_cur_dir(sess, SESSION_DIR_NONE);
};
}
+
+uint64_t session_manager_get_tcp_opening_sess_num(struct session_manager *mgr)
+{
+ return mgr->tcp_opening_sess_num;
+}
+
+uint64_t session_manager_get_tcp_closing_sess_num(struct session_manager *mgr)
+{
+ return mgr->tcp_closing_sess_num;
+}
+
+uint64_t session_manager_get_tcp_active_sess_num(struct session_manager *mgr)
+{
+ return mgr->tcp_active_sess_num;
+}
+
+uint64_t session_manager_get_udp_opening_sess_num(struct session_manager *mgr)
+{
+ return mgr->udp_opening_sess_num;
+}
+
+uint64_t session_manager_get_udp_closing_sess_num(struct session_manager *mgr)
+{
+ return mgr->udp_closing_sess_num;
+}
+
+uint64_t session_manager_get_udp_active_sess_num(struct session_manager *mgr)
+{
+ return mgr->udp_active_sess_num;
+}
diff --git a/src/session/session_manager.h b/src/session/session_manager.h
index e9b6bf4..c60ef14 100644
--- a/src/session/session_manager.h
+++ b/src/session/session_manager.h
@@ -8,24 +8,40 @@ extern "C"
#include "session.h"
-/*
- * session manager = session pool + session table + session timer
- *
- * session pool : alloc and free session
- * session table : find session by session key
- * session timer : session timeout
- * session manager: manage session pool, session table and session timer
- */
+// #define SESSION_MANAGER_LOG_ERROR(format, ...) void(0)
+#ifndef SESSION_MANAGER_LOG_ERROR
+#define SESSION_MANAGER_LOG_ERROR(format, ...) \
+ fprintf(stderr, "ERROR (session manager), " format "\n", ##__VA_ARGS__);
+#endif
+// #define SESSION_MANAGER_LOG_DEBUG(format, ...) void(0)
+#ifndef SESSION_MANAGER_LOG_DEBUG
+#define SESSION_MANAGER_LOG_DEBUG(format, ...) \
+ fprintf(stderr, "DEBUG (session manager), " format "\n", ##__VA_ARGS__);
+#endif
+// create and destroy
struct session_manager;
struct session_manager *session_manager_create(uint64_t max_session_num);
void session_manager_destroy(struct session_manager *mgr);
+// config
typedef void (*session_event_cb)(struct session *sess, uint32_t event, void *arg);
void session_manager_set_session_eventcb(struct session_manager *mgr, session_event_cb cb, void *arg);
+void session_manager_set_packet_timeout(struct session_manager *mgr, uint64_t timeout_ms);
+void session_manager_set_closing_timeout(struct session_manager *mgr, uint64_t timeout_ms);
+
+// core functions
struct session *session_manager_find_session(struct session_manager *mgr, const struct packet *pkt);
void session_manager_dispatch(struct session_manager *mgr);
+// for debug
+uint64_t session_manager_get_tcp_opening_sess_num(struct session_manager *mgr);
+uint64_t session_manager_get_tcp_closing_sess_num(struct session_manager *mgr);
+uint64_t session_manager_get_tcp_active_sess_num(struct session_manager *mgr);
+uint64_t session_manager_get_udp_opening_sess_num(struct session_manager *mgr);
+uint64_t session_manager_get_udp_closing_sess_num(struct session_manager *mgr);
+uint64_t session_manager_get_udp_active_sess_num(struct session_manager *mgr);
+
#ifdef __cpluscplus
}
#endif
diff --git a/src/session/session_private.h b/src/session/session_private.h
index 5018c4f..5d565aa 100644
--- a/src/session/session_private.h
+++ b/src/session/session_private.h
@@ -17,6 +17,29 @@ extern "C"
#define EX_DATA_MAX_COUNT 128
#define SESSION_EVENT_QUEUE_SIZE 256
+enum tcp_ex_data
+{
+ // HANDSHAKE
+ TCP_SYN_RECVED = 1 << 0,
+ TCP_SYNACK_RECVED = 1 << 1,
+ TCP_ACK_RECVED = 1 << 2,
+ // ESTABLISHED
+ TCP_C2S_PAYLOAD_RECVED = 1 << 3,
+ TCP_S2C_PAYLOAD_RECVED = 1 << 4,
+ // FIN
+ TCP_C2S_FIN_RECVED = 1 << 5,
+ TCP_S2C_FIN_RECVED = 1 << 6,
+ // RST
+ TCP_C2S_RST_RECVED = 1 << 7,
+ TCP_S2C_RST_RECVED = 1 << 8,
+};
+
+enum udp_ex_data
+{
+ UDP_C2S_RECVED = 1 << 0,
+ UDP_S2C_RECVED = 1 << 1,
+};
+
struct event_queue
{
uint32_t head_idx;
@@ -92,6 +115,7 @@ struct session
// session table key
struct tuple6 tuple;
+ enum session_dir tuple_dir;
struct session *next_ptr;
struct session *prev_ptr;
@@ -100,12 +124,17 @@ struct session
UT_hash_handle hh;
/******************************
- * Session Manager Zone
+ * Session Queue Zone
******************************/
struct session *next_ready_ptr;
};
+// tcp_builtin_ex = session_get_ex_new_index("tcp_builtin_ex", NULL, NULL);
+// udp_builtin_ex = session_get_ex_new_index("udp_builtin_ex", NULL, NULL);
+extern uint8_t tcp_builtin_ex;
+extern uint8_t udp_builtin_ex;
+
#ifdef __cpluscplus
}
#endif
diff --git a/src/session/session_queue.cpp b/src/session/session_queue.cpp
new file mode 100644
index 0000000..eb95188
--- /dev/null
+++ b/src/session/session_queue.cpp
@@ -0,0 +1,77 @@
+#include "session_queue.h"
+#include "session_private.h"
+
+struct session_queue
+{
+ struct session *head;
+ struct session *tail;
+ int count;
+};
+
+struct session_queue *session_queue_create()
+{
+ struct session_queue *queue = (struct session_queue *)calloc(1, sizeof(struct session_queue));
+ if (queue == NULL)
+ {
+ return NULL;
+ }
+ return queue;
+}
+
+void session_queue_destroy(struct session_queue *queue)
+{
+ if (queue)
+ {
+ free(queue);
+ queue = NULL;
+ }
+}
+
+void session_queue_push(struct session_queue *queue, struct session *sess)
+{
+ if (queue == NULL || sess == NULL)
+ {
+ return;
+ }
+
+ if (queue->head == NULL)
+ {
+ queue->head = sess;
+ queue->tail = sess;
+ }
+ else
+ {
+ queue->tail->next_ready_ptr = sess;
+ queue->tail = sess;
+ }
+ sess->next_ready_ptr = NULL;
+ queue->count++;
+}
+
+struct session *session_queue_pop(struct session_queue *queue)
+{
+ if (queue == NULL)
+ {
+ return NULL;
+ }
+
+ struct session *sess = queue->head;
+ if (sess == NULL)
+ {
+ return NULL;
+ }
+
+ if (queue->head == queue->tail)
+ {
+ queue->head = NULL;
+ queue->tail = NULL;
+ }
+ else
+ {
+ queue->head = sess->next_ready_ptr;
+ }
+ sess->next_ready_ptr = NULL;
+ queue->count--;
+
+ return sess;
+} \ No newline at end of file
diff --git a/src/session/session_queue.h b/src/session/session_queue.h
new file mode 100644
index 0000000..16cf288
--- /dev/null
+++ b/src/session/session_queue.h
@@ -0,0 +1,22 @@
+#ifndef _SESSION_QUEUE_H
+#define _SESSION_QUEUE_H
+
+#ifdef __cpluscplus
+extern "C"
+{
+#endif
+
+#include "session.h"
+
+struct session_queue;
+struct session_queue *session_queue_create();
+void session_queue_destroy(struct session_queue *queue);
+
+void session_queue_push(struct session_queue *queue, struct session *sess);
+struct session *session_queue_pop(struct session_queue *queue);
+
+#ifdef __cpluscplus
+}
+#endif
+
+#endif
diff --git a/src/session/session_table.cpp b/src/session/session_table.cpp
index a56a64a..48b72b4 100644
--- a/src/session/session_table.cpp
+++ b/src/session/session_table.cpp
@@ -12,8 +12,8 @@ struct session_table
void *arg;
uint64_t count;
- struct session *oldest_ptr;
- struct session *newest_ptr;
+ struct session *least_recently_unused;
+ struct session *least_recently_used;
};
/******************************************************************************
@@ -52,19 +52,19 @@ static void session_table_add_session_to_linklist(struct session_table *table, s
return;
}
- if (table->newest_ptr == NULL)
+ if (table->least_recently_used == NULL)
{
- table->oldest_ptr = sess;
- table->newest_ptr = sess;
+ table->least_recently_unused = sess;
+ table->least_recently_used = sess;
sess->prev_ptr = NULL;
sess->next_ptr = NULL;
}
else
{
- sess->next_ptr = table->newest_ptr;
- table->newest_ptr->prev_ptr = sess;
+ sess->next_ptr = table->least_recently_used;
+ table->least_recently_used->prev_ptr = sess;
sess->prev_ptr = NULL;
- table->newest_ptr = sess;
+ table->least_recently_used = sess;
}
}
@@ -77,17 +77,17 @@ static void session_table_del_session_from_linklist(struct session_table *table,
if (sess->prev_ptr == NULL && sess->next_ptr == NULL)
{
- table->oldest_ptr = NULL;
- table->newest_ptr = NULL;
+ table->least_recently_unused = NULL;
+ table->least_recently_used = NULL;
}
else if (sess->prev_ptr == NULL && sess->next_ptr != NULL)
{
- table->newest_ptr = sess->next_ptr;
+ table->least_recently_used = sess->next_ptr;
sess->next_ptr->prev_ptr = NULL;
}
else if (sess->prev_ptr != NULL && sess->next_ptr == NULL)
{
- table->oldest_ptr = sess->prev_ptr;
+ table->least_recently_unused = sess->prev_ptr;
sess->prev_ptr->next_ptr = NULL;
}
else
@@ -107,8 +107,8 @@ struct session_table *session_table_create()
{
struct session_table *table = (struct session_table *)calloc(1, sizeof(struct session_table));
table->count = 0;
- table->oldest_ptr = NULL;
- table->newest_ptr = NULL;
+ table->least_recently_unused = NULL;
+ table->least_recently_used = NULL;
return table;
}
@@ -204,25 +204,31 @@ struct session *session_table_find_session(struct session_table *table, const st
struct session *sess = NULL;
HASH_FIND(hh, table->root, tuple, sizeof(struct tuple6), sess);
+ if (sess)
+ {
+ session_table_del_session_from_linklist(table, sess);
+ session_table_add_session_to_linklist(table, sess);
+ }
+
return sess;
}
-struct session *session_table_find_oldest_session(struct session_table *table)
+struct session *session_table_find_least_recently_unused_session(struct session_table *table)
{
if (table == NULL)
{
return NULL;
}
- return table->oldest_ptr;
+ return table->least_recently_unused;
}
-struct session *session_table_find_newest_session(struct session_table *table)
+struct session *session_table_find_least_recently_used_session(struct session_table *table)
{
if (table == NULL)
{
return NULL;
}
- return table->newest_ptr;
+ return table->least_recently_used;
} \ No newline at end of file
diff --git a/src/session/session_table.h b/src/session/session_table.h
index 9bd9025..4dd2900 100644
--- a/src/session/session_table.h
+++ b/src/session/session_table.h
@@ -20,8 +20,8 @@ void session_table_set_freecb(struct session_table *table, session_free_cb free_
int session_table_add_session(struct session_table *table, const struct tuple6 *tuple, struct session *sess);
void session_table_delete_session(struct session_table *table, const struct tuple6 *tuple);
struct session *session_table_find_session(struct session_table *table, const struct tuple6 *tuple);
-struct session *session_table_find_oldest_session(struct session_table *table);
-struct session *session_table_find_newest_session(struct session_table *table);
+struct session *session_table_find_least_recently_unused_session(struct session_table *table);
+struct session *session_table_find_least_recently_used_session(struct session_table *table);
#ifdef __cpluscplus
}