From 2c268791823cb9cf1f0d9bf6f50c4061a1efa436 Mon Sep 17 00:00:00 2001 From: luwenpeng Date: Tue, 19 Dec 2023 10:47:26 +0800 Subject: [PATCH] implementation session manager --- src/packet/packet.cpp | 48 +- src/packet/packet.h | 4 +- src/session/CMakeLists.txt | 19 +- src/session/gtest_session_manager.cpp | 1198 +++++++++++++++++++++++++ src/session/gtest_session_queue.cpp | 29 + src/session/gtest_session_table.cpp | 28 +- src/session/session.cpp | 231 ++++- src/session/session.h | 48 +- src/session/session_manager.cpp | 649 ++++++++++++-- src/session/session_manager.h | 32 +- src/session/session_private.h | 31 +- src/session/session_queue.cpp | 77 ++ src/session/session_queue.h | 22 + src/session/session_table.cpp | 42 +- src/session/session_table.h | 4 +- 15 files changed, 2269 insertions(+), 193 deletions(-) create mode 100644 src/session/gtest_session_manager.cpp create mode 100644 src/session/gtest_session_queue.cpp create mode 100644 src/session/session_queue.cpp create mode 100644 src/session/session_queue.h 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 + +#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 + +#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 #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,110 +6,507 @@ #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) - /****************************************************************************** - * private API + * utils ******************************************************************************/ -static void session_manager_handle_new_session(struct session_manager *mgr, struct session_key *key, struct session *sess, const struct packet *pkt) +// TODO +static uint64_t alloc_session_id(void) { - // TODO + return 0; } -static void session_manager_handle_old_session(struct session_manager *mgr, struct session_key *key, struct session *sess, const struct packet *pkt) +// TODO +struct metadata *packet_get0_metadata(const struct packet *pkt) { - // TODO + static struct metadata md = {0}; + return &md; +}; + +/****************************************************************************** + * session manager counter + ******************************************************************************/ + +static void update_counter_on_opening(struct session_manager *mgr, struct session *sess) +{ + 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++; + } + } } -// 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_active(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_active_sess_num++; + } + else + { + mgr->udp_opening_sess_num--; + mgr->udp_active_sess_num++; + } + } +} + +static void update_counter_on_closing(struct session_manager *mgr, struct session *sess) +{ + 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 (session_get_state(sess) == SESSION_STATE_ACTIVE) + { + 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; + } +} + +static void update_counter_on_closed(struct session_manager *mgr, struct session *sess) +{ + if (session_get_state(sess) == SESSION_STATE_CLOSING) + { + if (session_get_type(sess) == SESSION_TYPE_TCP) + { + mgr->tcp_closing_sess_num--; + } + else + { + mgr->udp_closing_sess_num--; + } + } +} + +/****************************************************************************** + * judge session direction + ******************************************************************************/ + +static enum session_dir judge_direction_by_tuple6(const struct tuple6 *key) +{ + // big port is client + if (ntohs(key->src_port) > ntohs(key->dst_port)) + { + return SESSION_DIR_C2S; + } + else + { + return SESSION_DIR_S2C; + } +} + +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) + { + return session_get_tuple6_dir(sess); + } + else + { + if (session_get_tuple6_dir(sess) == SESSION_DIR_C2S) + { + return SESSION_DIR_S2C; + } + else + { + return SESSION_DIR_C2S; + } + } +} + +/****************************************************************************** + * 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); +} + +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); + + 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); +} + +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_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 (mgr->queue_head_ptr == NULL) + if (packet_has_tcp(pkt)) { - mgr->queue_head_ptr = sess; - mgr->queue_tail_ptr = sess; - sess->next_ready_ptr = NULL; + handle_tcp_old_session(mgr, key, sess, pkt); } else { - mgr->queue_tail_ptr->next_ready_ptr = sess; - mgr->queue_tail_ptr = sess; - sess->next_ready_ptr = NULL; + handle_udp_old_session(mgr, key, sess, pkt); } } -// Dequeue ready session from queue head -struct session *session_manager_ready_session_dequeue(struct session_manager *mgr) -{ - if (mgr == NULL) - { - return NULL; - } - - struct session *sess = mgr->queue_head_ptr; - if (sess == NULL) - { - return NULL; - } - - if (mgr->queue_head_ptr == mgr->queue_tail_ptr) - { - mgr->queue_head_ptr = NULL; - mgr->queue_tail_ptr = NULL; - } - else - { - mgr->queue_head_ptr = sess->next_ready_ptr; - } - - sess->next_ready_ptr = NULL; - return sess; -} - -// handshake expire set to discard -static void handshake_expire_cb(struct session *sess, void *arg) -{ - 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); -} - -// data expire set to closing -static void data_expire_cb(struct session *sess, void *arg) -{ - struct session_manager *mgr = (struct session_manager *)arg; - assert(mgr != NULL); - - session_set_state(sess, SESSION_STATE_CLOSING); - session_push_event(sess, SESSION_EVENT_CLOSING); - session_manager_enqueue_ready_session(mgr, sess); -} - /****************************************************************************** * public API ******************************************************************************/ @@ -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 }