#include #include "tcp_reassembly.h" #if 1 TEST(TCP_REASSEMBLY, ORDER) { struct tcp_segment *seg; struct tcp_reassembly *queue = tcp_reassembly_new(10, 16); EXPECT_TRUE(queue != NULL); tcp_reassembly_set_recv_next(queue, 90); /* * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |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 */ seg = tcp_segment_new(90, "0123456789", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 0) == 0); seg = tcp_segment_new(100, "abcdefghij", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 0) == 0); seg = tcp_segment_new(110, "ABCDEFGHIJ", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 0) == 0); seg = tcp_reassembly_pop(queue); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(seg->len == 10); EXPECT_TRUE(memcmp(seg->data, "0123456789", seg->len) == 0); tcp_segment_free(seg); seg = tcp_reassembly_pop(queue); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(seg->len == 10); EXPECT_TRUE(memcmp(seg->data, "abcdefghij", seg->len) == 0); tcp_segment_free(seg); seg = tcp_reassembly_pop(queue); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(seg->len == 10); EXPECT_TRUE(memcmp(seg->data, "ABCDEFGHIJ", seg->len) == 0); tcp_segment_free(seg); EXPECT_TRUE(tcp_reassembly_pop(queue) == NULL); tcp_reassembly_free(queue); } #endif #if 1 TEST(TCP_REASSEMBLY, OUT_OF_ORDER) { struct tcp_segment *seg; struct tcp_reassembly *queue = tcp_reassembly_new(10, 16); EXPECT_TRUE(queue != NULL); tcp_reassembly_set_recv_next(queue, 90); /* * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |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 */ seg = tcp_segment_new(110, "ABCDEFGHIJ", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 0) == 0); seg = tcp_segment_new(100, "abcdefghij", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 0) == 0); seg = tcp_segment_new(90, "0123456789", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 0) == 0); seg = tcp_reassembly_pop(queue); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(seg->len == 10); EXPECT_TRUE(memcmp(seg->data, "0123456789", seg->len) == 0); tcp_segment_free(seg); seg = tcp_reassembly_pop(queue); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(seg->len == 10); EXPECT_TRUE(memcmp(seg->data, "abcdefghij", seg->len) == 0); tcp_segment_free(seg); seg = tcp_reassembly_pop(queue); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(seg->len == 10); EXPECT_TRUE(memcmp(seg->data, "ABCDEFGHIJ", seg->len) == 0); tcp_segment_free(seg); EXPECT_TRUE(tcp_reassembly_pop(queue) == NULL); tcp_reassembly_free(queue); } #endif #if 1 TEST(TCP_REASSEMBLY, REPEAT) { struct tcp_segment *seg; struct tcp_reassembly *queue = tcp_reassembly_new(10, 16); EXPECT_TRUE(queue != NULL); tcp_reassembly_set_recv_next(queue, 100); /* * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |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 */ seg = tcp_segment_new(90, "0123456789", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 0) == 0); seg = tcp_segment_new(100, "abcdefghij", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 0) == 0); seg = tcp_segment_new(100, "ABCDEFGHIJ", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 0) == -2); // repeat tcp_segment_free(seg); seg = tcp_reassembly_pop(queue); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(seg->len == 10); EXPECT_TRUE(memcmp(seg->data, "abcdefghij", seg->len) == 0); tcp_segment_free(seg); EXPECT_TRUE(tcp_reassembly_pop(queue) == NULL); tcp_reassembly_free(queue); } #endif #if 1 TEST(TCP_REASSEMBLY, OVERLAP) { struct tcp_segment *seg; struct tcp_reassembly *queue = tcp_reassembly_new(10, 16); EXPECT_TRUE(queue != NULL); tcp_reassembly_set_recv_next(queue, 90); /* * +-+-+-+-+-+-+-+-+-+-+ * |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| * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ seg = tcp_segment_new(90, "0123456789", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 0) == 0); seg = tcp_segment_new(96, "abcdefghij", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 0) == 1); seg = tcp_segment_new(102, "ABCDEFGHIJ", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 0) == 1); seg = tcp_reassembly_pop(queue); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(seg->len == 10); EXPECT_TRUE(memcmp(seg->data, "0123456789", seg->len) == 0); tcp_segment_free(seg); seg = tcp_reassembly_pop(queue); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(seg->len == 6); EXPECT_TRUE(memcmp(seg->data, "efghij", seg->len) == 0); tcp_segment_free(seg); seg = tcp_reassembly_pop(queue); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(seg->len == 6); EXPECT_TRUE(memcmp(seg->data, "EFGHIJ", seg->len) == 0); tcp_segment_free(seg); EXPECT_TRUE(tcp_reassembly_pop(queue) == NULL); tcp_reassembly_free(queue); } #endif #if 1 TEST(TCP_REASSEMBLY, SEQ_WRAPAROUND) { struct tcp_segment *seg; struct tcp_reassembly *queue = tcp_reassembly_new(10, 16); EXPECT_TRUE(queue != NULL); // UINT32_MAX = 4294967295 printf("UINT32_MAX = %u\n", UINT32_MAX); tcp_reassembly_set_recv_next(queue, UINT32_MAX - 10); /* * +-+-+-+-+-+-+-+-+-+-+ * |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| * | | | +-+-+-+-+-+-+-+-+-+-+ * | | | | | | * | | | | | +---> 10 * | | | | +---> 4 * | | | +---> 1 * | | +---> 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| * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ seg = tcp_segment_new(UINT32_MAX - 10, "0123456789", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 0) == 0); seg = tcp_segment_new(UINT32_MAX - 4, "abcdefghij", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 0) == 1); seg = tcp_segment_new(1, "ABCDEFGHIJ", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 0) == 0); seg = tcp_reassembly_pop(queue); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(seg->len == 10); EXPECT_TRUE(memcmp(seg->data, "0123456789", seg->len) == 0); tcp_segment_free(seg); seg = tcp_reassembly_pop(queue); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(seg->len == 6); EXPECT_TRUE(memcmp(seg->data, "efghij", seg->len) == 0); tcp_segment_free(seg); seg = tcp_reassembly_pop(queue); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(seg->len == 6); EXPECT_TRUE(memcmp(seg->data, "EFGHIJ", seg->len) == 0); tcp_segment_free(seg); EXPECT_TRUE(tcp_reassembly_pop(queue) == NULL); tcp_reassembly_free(queue); } #endif #if 1 TEST(TCP_REASSEMBLY, MAX_TIMEOUT) { struct tcp_segment *seg; struct tcp_reassembly *queue = tcp_reassembly_new(10, 16); EXPECT_TRUE(queue != NULL); tcp_reassembly_set_recv_next(queue, 90); /* * +-+-+-+-+-+-+-+-+-+-+ * |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 +-->95 +---> 100 */ seg = tcp_segment_new(90, "0123456789", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 1) == 0); seg = tcp_segment_new(95, "ABCDEFGHIJ", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 2) == 1); seg = tcp_segment_new(100, "abcdefghij", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 3) == 1); seg = tcp_reassembly_expire(queue, 11); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(seg->len == 10); EXPECT_TRUE(memcmp(seg->data, "0123456789", seg->len) == 0); tcp_segment_free(seg); seg = tcp_reassembly_expire(queue, 11); EXPECT_TRUE(seg == NULL); tcp_reassembly_inc_recv_next(queue, 10); seg = tcp_reassembly_pop(queue); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(seg->len == 5); EXPECT_TRUE(memcmp(seg->data, "FGHIJ", seg->len) == 0); tcp_segment_free(seg); seg = tcp_reassembly_pop(queue); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(seg->len == 5); EXPECT_TRUE(memcmp(seg->data, "fghij", seg->len) == 0); tcp_segment_free(seg); EXPECT_TRUE(tcp_reassembly_pop(queue) == NULL); tcp_reassembly_free(queue); } #endif #if 1 TEST(TCP_REASSEMBLY, MAX_PACKETS) { struct tcp_segment *seg; struct tcp_reassembly *queue = tcp_reassembly_new(10, 2); EXPECT_TRUE(queue != NULL); tcp_reassembly_set_recv_next(queue, 90); /* * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |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 */ seg = tcp_segment_new(90, "0123456789", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 0) == 0); seg = tcp_segment_new(100, "abcdefghij", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 1) == 0); seg = tcp_segment_new(100, "ABCDEFGHIJ", 10); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(tcp_reassembly_push(queue, seg, 2) == -1); tcp_segment_free(seg); seg = tcp_reassembly_pop(queue); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(seg->len == 10); EXPECT_TRUE(memcmp(seg->data, "0123456789", seg->len) == 0); tcp_segment_free(seg); seg = tcp_reassembly_pop(queue); EXPECT_TRUE(seg != NULL); EXPECT_TRUE(seg->len == 10); EXPECT_TRUE(memcmp(seg->data, "abcdefghij", seg->len) == 0); tcp_segment_free(seg); EXPECT_TRUE(tcp_reassembly_pop(queue) == NULL); tcp_reassembly_free(queue); } #endif int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }