#include #include "tcp_reassembly.h" static void tcp_reassembly_check_stat(struct tcp_reassembly *assy, uint64_t curr_segments, uint64_t curr_bytes, uint64_t insert_segments, uint64_t insert_bytes, uint64_t remove_segments, uint64_t remove_bytes, uint64_t consume_segments, uint64_t consume_bytes, uint64_t retrans_bypass_segments, uint64_t retrans_bypass_bytes, uint64_t overload_bypass_segments, uint64_t overload_bypass_bytes, uint64_t timeout_discard_segments, uint64_t timeout_discard_bytes) { struct tcp_reassembly_stat *stat = tcp_reassembly_get_stat(assy); EXPECT_TRUE(stat != NULL); EXPECT_TRUE(stat->curr_segments == curr_segments); EXPECT_TRUE(stat->curr_bytes == curr_bytes); EXPECT_TRUE(stat->insert_segments == insert_segments); EXPECT_TRUE(stat->insert_bytes == insert_bytes); EXPECT_TRUE(stat->remove_segments == remove_segments); EXPECT_TRUE(stat->remove_bytes == remove_bytes); EXPECT_TRUE(stat->consume_segments == consume_segments); EXPECT_TRUE(stat->consume_bytes == consume_bytes); EXPECT_TRUE(stat->retrans_bypass_segments == retrans_bypass_segments); EXPECT_TRUE(stat->retrans_bypass_bytes == retrans_bypass_bytes); EXPECT_TRUE(stat->overload_bypass_segments == overload_bypass_segments); EXPECT_TRUE(stat->overload_bypass_bytes == overload_bypass_bytes); EXPECT_TRUE(stat->timeout_discard_segments == timeout_discard_segments); EXPECT_TRUE(stat->timeout_discard_bytes == timeout_discard_bytes); } #if 0 const char *session_peek_tcp_payload(struct session *session, uint32_t *len) { struct tcp_reassembly *assy; struct session_dir *dir = session_get_cur_dir(session); if (dir == SESSION_DIR_C2S) { assy = session_get_tcp_c2s_reassembly(session); } else { assy = session_get_tcp_s2c_reassembly(session); } return tcp_reassembly_peek(assy, len); } void session_consume_tcp_payload(struct session *session, uint32_t len) { struct tcp_reassembly *assy; struct session_dir *dir = session_get_cur_dir(session); if (dir == SESSION_DIR_C2S) { assy = session_get_tcp_c2s_reassembly(session); } else { assy = session_get_tcp_s2c_reassembly(session); } tcp_reassembly_consume(assy, len); } #endif #if 1 TEST(TCP_REASSEMBLY, TEST) { uint32_t len; const char *ptr; struct tcp_reassembly *assy; struct tcp_reassembly_options opts = { .enable = true, .max_timeout = 10, .max_segments = 16, .max_bytes = 1500}; assy = tcp_reassembly_new(&opts); EXPECT_TRUE(assy != NULL); tcp_reassembly_check_stat(assy, 0, 0, // curr_segments, curr_bytes 0, 0, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_init(assy, 99); /* * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|g|h|i|j|A|B|C|D|E|F|G|H|I|J| * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | | * +---> 90 +---> 100 +---> 110 */ tcp_reassembly_insert(assy, 90, (const char *)"0123456789", 10, 0); tcp_reassembly_check_stat(assy, 1, 10, // curr_segments, curr_bytes 1, 10, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_insert(assy, 100, (const char *)"abcdefghij", 10, 0); tcp_reassembly_check_stat(assy, 2, 20, // curr_segments, curr_bytes 2, 20, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_insert(assy, 110, (const char *)"ABCDEFGHIJ", 10, 0); tcp_reassembly_check_stat(assy, 3, 30, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr != NULL); EXPECT_TRUE(len == 10); EXPECT_TRUE(memcmp(ptr, "abcdefghij", len) == 0); ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr != NULL); EXPECT_TRUE(len == 10); EXPECT_TRUE(memcmp(ptr, "abcdefghij", len) == 0); tcp_reassembly_consume(assy, len); tcp_reassembly_check_stat(assy, 2, 20, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 1, 10, // remove_segments, remove_bytes 1, 10, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr != NULL); EXPECT_TRUE(len == 10); EXPECT_TRUE(memcmp(ptr, "ABCDEFGHIJ", len) == 0); tcp_reassembly_consume(assy, len); tcp_reassembly_check_stat(assy, 1, 10, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 2, 20, // remove_segments, remove_bytes 2, 20, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr == NULL); tcp_reassembly_free(assy); } #endif #if 1 TEST(TCP_REASSEMBLY, REPEAT1) { uint32_t len; const char *ptr; struct tcp_reassembly *assy; struct tcp_reassembly_options opts = { .enable = true, .max_timeout = 10, .max_segments = 16, .max_bytes = 1500}; assy = tcp_reassembly_new(&opts); EXPECT_TRUE(assy != NULL); tcp_reassembly_check_stat(assy, 0, 0, // curr_segments, curr_bytes 0, 0, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_init(assy, 99); /* * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|g|h|i|j| * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | |A|B|C|D|E|F|G|H|I|J| * | +-+-+-+-+-+-+-+-+-+-+ * | | | * +---> 90 +---> 100 +---> 109 */ tcp_reassembly_insert(assy, 90, (const char *)"0123456789", 10, 0); tcp_reassembly_check_stat(assy, 1, 10, // curr_segments, curr_bytes 1, 10, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_insert(assy, 100, (const char *)"abcdefghij", 10, 0); tcp_reassembly_check_stat(assy, 2, 20, // curr_segments, curr_bytes 2, 20, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_insert(assy, 100, (const char *)"ABCDEFGHIJ", 10, 0); tcp_reassembly_check_stat(assy, 3, 30, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr != NULL); EXPECT_TRUE(len == 10); EXPECT_TRUE(memcmp(ptr, "abcdefghij", len) == 0); tcp_reassembly_consume(assy, len); tcp_reassembly_check_stat(assy, 1, 10, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 2, 20, // remove_segments, remove_bytes 1, 10, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr == NULL); tcp_reassembly_free(assy); } #endif #if 1 TEST(TCP_REASSEMBLY, REPEAT2) { uint32_t len; const char *ptr; struct tcp_reassembly *assy; struct tcp_reassembly_options opts = { .enable = true, .max_timeout = 10, .max_segments = 16, .max_bytes = 1500}; assy = tcp_reassembly_new(&opts); EXPECT_TRUE(assy != NULL); tcp_reassembly_check_stat(assy, 0, 0, // curr_segments, curr_bytes 0, 0, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_init(assy, 99); /* * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|G|H|I|J| * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | |a|b|c|d|e|f|g|h|i|j| * | +-+-+-+-+-+-+-+-+-+-+ * | | | * +---> 90 +---> 100 +---> 109 */ // C2S tcp_reassembly_insert(assy, 90, (const char *)"0123456789", 10, 0); tcp_reassembly_check_stat(assy, 1, 10, // curr_segments, curr_bytes 1, 10, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_insert(assy, 100, (const char *)"ABCDEFGHIJ", 10, 0); tcp_reassembly_check_stat(assy, 2, 20, // curr_segments, curr_bytes 2, 20, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_insert(assy, 100, (const char *)"abcdefghij", 10, 0); tcp_reassembly_check_stat(assy, 3, 30, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr != NULL); EXPECT_TRUE(len == 10); EXPECT_TRUE(memcmp(ptr, "ABCDEFGHIJ", len) == 0); tcp_reassembly_consume(assy, len); tcp_reassembly_check_stat(assy, 1, 10, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 2, 20, // remove_segments, remove_bytes 1, 10, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr == NULL); tcp_reassembly_free(assy); } #endif #if 1 TEST(TCP_REASSEMBLY, OVERLAP) { uint32_t len; const char *ptr; struct tcp_reassembly *assy; struct tcp_reassembly_options opts = { .enable = true, .max_timeout = 10, .max_segments = 16, .max_bytes = 1500}; assy = tcp_reassembly_new(&opts); EXPECT_TRUE(assy != NULL); tcp_reassembly_check_stat(assy, 0, 0, // curr_segments, curr_bytes 0, 0, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_init(assy, 89); /* * +-+-+-+-+-+-+-+-+-+-+ * |0|1|2|3|4|5|6|7|8|9| * +-+-+-+-+-+-+-+-+-+-+ * | +-+-+-+-+-+-+-+-+-+-+ * | |a|b|c|d|e|f|g|h|i|j| * | +-+-+-+-+-+-+-+-+-+-+ * | | | +-+-+-+-+-+-+-+-+-+-+ * | | | |A|B|C|D|E|F|G|H|I|J| * | | | +-+-+-+-+-+-+-+-+-+-+ * | | | | | | * | | | | | +---> 111 * | | | | +---> 105 * | | | +---> 102 * | | +---> 99 * | +---> 96 * +---> 90 * * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |0|1|2|3|4|5|6|7|8|9|e|f|g|h|i|j|E|F|G|H|I|J| * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ tcp_reassembly_insert(assy, 90, (const char *)"0123456789", 10, 0); tcp_reassembly_check_stat(assy, 1, 10, // curr_segments, curr_bytes 1, 10, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_insert(assy, 96, (const char *)"abcdefghij", 10, 0); tcp_reassembly_check_stat(assy, 2, 20, // curr_segments, curr_bytes 2, 20, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_insert(assy, 102, (const char *)"ABCDEFGHIJ", 10, 0); tcp_reassembly_check_stat(assy, 3, 30, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr != NULL); EXPECT_TRUE(len == 10); EXPECT_TRUE(memcmp(ptr, "0123456789", len) == 0); tcp_reassembly_consume(assy, len); tcp_reassembly_check_stat(assy, 2, 20, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 1, 10, // remove_segments, remove_bytes 1, 10, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr != NULL); EXPECT_TRUE(len == 6); EXPECT_TRUE(memcmp(ptr, "efghij", len) == 0); tcp_reassembly_consume(assy, len); tcp_reassembly_check_stat(assy, 1, 10, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 2, 20, // remove_segments, remove_bytes 2, 16, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr != NULL); EXPECT_TRUE(len == 6); EXPECT_TRUE(memcmp(ptr, "EFGHIJ", len) == 0); tcp_reassembly_consume(assy, len); tcp_reassembly_check_stat(assy, 0, 0, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 3, 30, // remove_segments, remove_bytes 3, 22, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr == NULL); tcp_reassembly_free(assy); } #endif #if 1 TEST(TCP_REASSEMBLY, SEQ_WRAPAROUND) { uint32_t len; const char *ptr; struct tcp_reassembly *assy; struct tcp_reassembly_options opts = { .enable = true, .max_timeout = 10, .max_segments = 16, .max_bytes = 1500}; printf("UINT32_MAX = %u\n", UINT32_MAX); assy = tcp_reassembly_new(&opts); EXPECT_TRUE(assy != NULL); tcp_reassembly_check_stat(assy, 0, 0, // curr_segments, curr_bytes 0, 0, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_init(assy, UINT32_MAX - 11); /* * +-+-+-+-+-+-+-+-+-+-+ * |0|1|2|3|4|5|6|7|8|9| * +-+-+-+-+-+-+-+-+-+-+ * | +-+-+-+-+-+-+-+-+-+-+ * | |a|b|c|d|e|f|g|h|i|j| * | +-+-+-+-+-+-+-+-+-+-+ * | | | +-+-+-+-+-+-+-+-+-+-+ * | | | |A|B|C|D|E|F|G|H|I|J| * | | | +-+-+-+-+-+-+-+-+-+-+ * | | | | | | * | | | | | +---> UINT32_MAX + 11 * | | | | +---> UINT32_MAX + 5 * | | | +---> UINT32_MAX + 2 * | | +---> UINT32_MAX - 1 * | +---> UINT32_MAX - 4 * +---> UINT32_MAX - 10 * * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |0|1|2|3|4|5|6|7|8|9|e|f|g|h|i|j|E|F|G|H|I|J| * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ tcp_reassembly_insert(assy, UINT32_MAX - 10, (const char *)"0123456789", 10, 0); tcp_reassembly_check_stat(assy, 1, 10, // curr_segments, curr_bytes 1, 10, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_insert(assy, UINT32_MAX - 4, (const char *)"abcdefghij", 10, 0); tcp_reassembly_check_stat(assy, 2, 20, // curr_segments, curr_bytes 2, 20, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_insert(assy, 2, (const char *)"ABCDEFGHIJ", 10, 0); tcp_reassembly_check_stat(assy, 3, 30, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr != NULL); EXPECT_TRUE(len == 10); EXPECT_TRUE(memcmp(ptr, "0123456789", len) == 0); tcp_reassembly_consume(assy, len); tcp_reassembly_check_stat(assy, 2, 20, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 1, 10, // remove_segments, remove_bytes 1, 10, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr != NULL); EXPECT_TRUE(len == 6); EXPECT_TRUE(memcmp(ptr, "efghij", len) == 0); tcp_reassembly_consume(assy, len); tcp_reassembly_check_stat(assy, 1, 10, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 2, 20, // remove_segments, remove_bytes 2, 16, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr != NULL); EXPECT_TRUE(len == 6); EXPECT_TRUE(memcmp(ptr, "EFGHIJ", len) == 0); tcp_reassembly_consume(assy, len); tcp_reassembly_check_stat(assy, 0, 0, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 3, 30, // remove_segments, remove_bytes 3, 22, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr == NULL); tcp_reassembly_free(assy); } #endif #if 1 TEST(TCP_REASSEMBLY, MAX_TIMEOUT1) { uint32_t len; const char *ptr; struct tcp_reassembly *assy; struct tcp_reassembly_options opts = { .enable = true, .max_timeout = 10, .max_segments = 16, .max_bytes = 1500}; assy = tcp_reassembly_new(&opts); EXPECT_TRUE(assy != NULL); tcp_reassembly_check_stat(assy, 0, 0, // curr_segments, curr_bytes 0, 0, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_init(assy, 99); /* * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|g|h|i|j| * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | |A|B|C|D|E|F|G|H|I|J| * | +-+-+-+-+-+-+-+-+-+-+ * | | | * +---> 90 +---> 100 +---> 109 */ // C2S tcp_reassembly_insert(assy, 90, (const char *)"0123456789", 10, 0); tcp_reassembly_check_stat(assy, 1, 10, // curr_segments, curr_bytes 1, 10, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_insert(assy, 100, (const char *)"abcdefghij", 10, 1); tcp_reassembly_check_stat(assy, 2, 20, // curr_segments, curr_bytes 2, 20, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_insert(assy, 100, (const char *)"ABCDEFGHIJ", 10, 2); tcp_reassembly_check_stat(assy, 3, 30, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_expire(assy, 11); tcp_reassembly_check_stat(assy, 1, 10, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 2, 20); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr != NULL); EXPECT_TRUE(len == 10); EXPECT_TRUE(memcmp(ptr, "ABCDEFGHIJ", len) == 0); tcp_reassembly_consume(assy, len); tcp_reassembly_check_stat(assy, 0, 0, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 1, 10, // remove_segments, remove_bytes 1, 10, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 2, 20); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr == NULL); tcp_reassembly_free(assy); } #endif #if 1 // expire after consume TEST(TCP_REASSEMBLY, MAX_TIMEOUT2) { uint32_t len; const char *ptr; struct tcp_reassembly *assy; struct tcp_reassembly_options opts = { .enable = true, .max_timeout = 10, .max_segments = 16, .max_bytes = 1500}; assy = tcp_reassembly_new(&opts); EXPECT_TRUE(assy != NULL); tcp_reassembly_check_stat(assy, 0, 0, // curr_segments, curr_bytes 0, 0, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_init(assy, 89); /* * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|g|h|i|j| * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | |A|B|C|D|E|F|G|H|I|J| * | +-+-+-+-+-+-+-+-+-+-+ * | | | * +---> 90 +---> 100 +---> 109 */ tcp_reassembly_insert(assy, 90, (const char *)"0123456789", 10, 0); tcp_reassembly_check_stat(assy, 1, 10, // curr_segments, curr_bytes 1, 10, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_insert(assy, 100, (const char *)"abcdefghij", 10, 1); tcp_reassembly_check_stat(assy, 2, 20, // curr_segments, curr_bytes 2, 20, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_insert(assy, 100, (const char *)"ABCDEFGHIJ", 10, 2); tcp_reassembly_check_stat(assy, 3, 30, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr != NULL); EXPECT_TRUE(len == 10); EXPECT_TRUE(memcmp(ptr, "0123456789", len) == 0); tcp_reassembly_consume(assy, len); tcp_reassembly_check_stat(assy, 2, 20, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 1, 10, // remove_segments, remove_bytes 1, 10, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_expire(assy, 11); tcp_reassembly_check_stat(assy, 1, 10, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 1, 10, // remove_segments, remove_bytes 1, 10, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 1, 10); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr != NULL); EXPECT_TRUE(len == 10); EXPECT_TRUE(memcmp(ptr, "ABCDEFGHIJ", len) == 0); tcp_reassembly_consume(assy, len); tcp_reassembly_check_stat(assy, 0, 0, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 2, 20, // remove_segments, remove_bytes 2, 20, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 1, 10); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_free(assy); } #endif #if 1 TEST(TCP_REASSEMBLY, MAX_PACKETS) { uint32_t len; const char *ptr; struct tcp_reassembly *assy; struct tcp_reassembly_options opts = { .enable = true, .max_timeout = 10, .max_segments = 2, .max_bytes = 1500}; assy = tcp_reassembly_new(&opts); EXPECT_TRUE(assy != NULL); tcp_reassembly_check_stat(assy, 0, 0, // curr_segments, curr_bytes 0, 0, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_init(assy, 99); /* * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|g|h|i|j|A|B|C|D|E|F|G|H|I|J| * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | | * +---> 90 +---> 100 +---> 110 */ // C2S tcp_reassembly_insert(assy, 90, (const char *)"0123456789", 10, 0); tcp_reassembly_check_stat(assy, 1, 10, // curr_segments, curr_bytes 1, 10, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_insert(assy, 100, (const char *)"abcdefghij", 10, 0); tcp_reassembly_check_stat(assy, 2, 20, // curr_segments, curr_bytes 2, 20, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_insert(assy, 110, (const char *)"ABCDEFGHIJ", 10, 0); tcp_reassembly_check_stat(assy, 2, 20, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 1, 10, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr != NULL); EXPECT_TRUE(len == 10); EXPECT_TRUE(memcmp(ptr, "abcdefghij", len) == 0); ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr != NULL); EXPECT_TRUE(len == 10); EXPECT_TRUE(memcmp(ptr, "abcdefghij", len) == 0); tcp_reassembly_consume(assy, len); tcp_reassembly_check_stat(assy, 1, 10, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 1, 10, // remove_segments, remove_bytes 1, 10, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 1, 10, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr == NULL); tcp_reassembly_free(assy); } #endif #if 1 TEST(TCP_REASSEMBLY, MAX_BYTES) { uint32_t len; const char *ptr; struct tcp_reassembly *assy; struct tcp_reassembly_options opts = { .enable = true, .max_timeout = 10, .max_segments = 16, .max_bytes = 20}; assy = tcp_reassembly_new(&opts); EXPECT_TRUE(assy != NULL); tcp_reassembly_check_stat(assy, 0, 0, // curr_segments, curr_bytes 0, 0, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_init(assy, 99); /* * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|g|h|i|j|A|B|C|D|E|F|G|H|I|J| * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | | * +---> 90 +---> 100 +---> 110 */ // C2S tcp_reassembly_insert(assy, 90, (const char *)"0123456789", 10, 0); tcp_reassembly_check_stat(assy, 1, 10, // curr_segments, curr_bytes 1, 10, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_insert(assy, 100, (const char *)"abcdefghij", 10, 0); tcp_reassembly_check_stat(assy, 2, 20, // curr_segments, curr_bytes 2, 20, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 0, 0, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes tcp_reassembly_insert(assy, 110, (const char *)"ABCDEFGHIJ", 10, 0); tcp_reassembly_check_stat(assy, 2, 20, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 0, 0, // remove_segments, remove_bytes 0, 0, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 1, 10, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr != NULL); EXPECT_TRUE(len == 10); EXPECT_TRUE(memcmp(ptr, "abcdefghij", len) == 0); ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr != NULL); EXPECT_TRUE(len == 10); EXPECT_TRUE(memcmp(ptr, "abcdefghij", len) == 0); tcp_reassembly_consume(assy, len); tcp_reassembly_check_stat(assy, 1, 10, // curr_segments, curr_bytes 3, 30, // insert_segments, insert_bytes 1, 10, // remove_segments, remove_bytes 1, 10, // consume_segments, consume_bytes 0, 0, // retrans_bypass_segments, retrans_bypass_bytes 1, 10, // overload_bypass_segments, overload_bypass_bytes 0, 0); // timeout_discard_segments, timeout_discard_bytes ptr = tcp_reassembly_peek(assy, &len); EXPECT_TRUE(ptr == NULL); tcp_reassembly_free(assy); } #endif int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }