test_tcp_oos.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. #include "test_tcp_oos.h"
  2. #include "lwip/tcp.h"
  3. #include "lwip/stats.h"
  4. #include "tcp_helper.h"
  5. #if !LWIP_STATS || !TCP_STATS || !MEMP_STATS
  6. #error "This tests needs TCP- and MEMP-statistics enabled"
  7. #endif
  8. #if !TCP_QUEUE_OOSEQ
  9. #error "This tests needs TCP_QUEUE_OOSEQ enabled"
  10. #endif
  11. /** CHECK_SEGMENTS_ON_OOSEQ:
  12. * 1: check count, seqno and len of segments on pcb->ooseq (strict)
  13. * 0: only check that bytes are received in correct order (less strict) */
  14. #define CHECK_SEGMENTS_ON_OOSEQ 1
  15. #if CHECK_SEGMENTS_ON_OOSEQ
  16. #define EXPECT_OOSEQ(x) EXPECT(x)
  17. #else
  18. #define EXPECT_OOSEQ(x)
  19. #endif
  20. /* helper functions */
  21. /** Get the numbers of segments on the ooseq list */
  22. static int tcp_oos_count(struct tcp_pcb* pcb)
  23. {
  24. int num = 0;
  25. struct tcp_seg* seg = pcb->ooseq;
  26. while(seg != NULL) {
  27. num++;
  28. seg = seg->next;
  29. }
  30. return num;
  31. }
  32. /** Get the seqno of a segment (by index) on the ooseq list
  33. *
  34. * @param pcb the pcb to check for ooseq segments
  35. * @param seg_index index of the segment on the ooseq list
  36. * @return seqno of the segment
  37. */
  38. static u32_t
  39. tcp_oos_seg_seqno(struct tcp_pcb* pcb, int seg_index)
  40. {
  41. int num = 0;
  42. struct tcp_seg* seg = pcb->ooseq;
  43. /* then check the actual segment */
  44. while(seg != NULL) {
  45. if(num == seg_index) {
  46. return seg->tcphdr->seqno;
  47. }
  48. num++;
  49. seg = seg->next;
  50. }
  51. fail();
  52. return 0;
  53. }
  54. /** Get the tcplen of a segment (by index) on the ooseq list
  55. *
  56. * @param pcb the pcb to check for ooseq segments
  57. * @param seg_index index of the segment on the ooseq list
  58. * @return tcplen of the segment
  59. */
  60. static int
  61. tcp_oos_seg_tcplen(struct tcp_pcb* pcb, int seg_index)
  62. {
  63. int num = 0;
  64. struct tcp_seg* seg = pcb->ooseq;
  65. /* then check the actual segment */
  66. while(seg != NULL) {
  67. if(num == seg_index) {
  68. return TCP_TCPLEN(seg);
  69. }
  70. num++;
  71. seg = seg->next;
  72. }
  73. fail();
  74. return -1;
  75. }
  76. /* Setup/teardown functions */
  77. static void
  78. tcp_oos_setup(void)
  79. {
  80. tcp_remove_all();
  81. }
  82. static void
  83. tcp_oos_teardown(void)
  84. {
  85. tcp_remove_all();
  86. }
  87. /* Test functions */
  88. /** create multiple segments and pass them to tcp_input in a wrong
  89. * order to see if ooseq-caching works correctly
  90. * FIN is received in out-of-sequence segments only */
  91. START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ)
  92. {
  93. struct test_tcp_counters counters;
  94. struct tcp_pcb* pcb;
  95. struct pbuf *p_8_9, *p_4_8, *p_4_10, *p_2_14, *p_fin, *pinseq;
  96. char data[] = {
  97. 1, 2, 3, 4,
  98. 5, 6, 7, 8,
  99. 9, 10, 11, 12,
  100. 13, 14, 15, 16};
  101. struct ip_addr remote_ip, local_ip;
  102. u16_t data_len;
  103. u16_t remote_port = 0x100, local_port = 0x101;
  104. struct netif netif;
  105. LWIP_UNUSED_ARG(_i);
  106. /* initialize local vars */
  107. memset(&netif, 0, sizeof(netif));
  108. IP4_ADDR(&local_ip, 192, 168, 1, 1);
  109. IP4_ADDR(&remote_ip, 192, 168, 1, 2);
  110. data_len = sizeof(data);
  111. /* initialize counter struct */
  112. memset(&counters, 0, sizeof(counters));
  113. counters.expected_data_len = data_len;
  114. counters.expected_data = data;
  115. /* create and initialize the pcb */
  116. pcb = test_tcp_new_counters_pcb(&counters);
  117. EXPECT_RET(pcb != NULL);
  118. tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
  119. /* create segments */
  120. /* pinseq is sent as last segment! */
  121. pinseq = tcp_create_rx_segment(pcb, &data[0], 4, 0, 0, TCP_ACK);
  122. /* p1: 8 bytes before FIN */
  123. /* seqno: 8..16 */
  124. p_8_9 = tcp_create_rx_segment(pcb, &data[8], 8, 8, 0, TCP_ACK|TCP_FIN);
  125. /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */
  126. /* seqno: 4..11 */
  127. p_4_8 = tcp_create_rx_segment(pcb, &data[4], 8, 4, 0, TCP_ACK);
  128. /* p3: same as p2 but 2 bytes longer */
  129. /* seqno: 4..13 */
  130. p_4_10 = tcp_create_rx_segment(pcb, &data[4], 10, 4, 0, TCP_ACK);
  131. /* p4: 14 bytes before FIN, includes data from p1 and p2, plus partly from pinseq */
  132. /* seqno: 2..15 */
  133. p_2_14 = tcp_create_rx_segment(pcb, &data[2], 14, 2, 0, TCP_ACK);
  134. /* FIN, seqno 16 */
  135. p_fin = tcp_create_rx_segment(pcb, NULL, 0,16, 0, TCP_ACK|TCP_FIN);
  136. EXPECT(pinseq != NULL);
  137. EXPECT(p_8_9 != NULL);
  138. EXPECT(p_4_8 != NULL);
  139. EXPECT(p_4_10 != NULL);
  140. EXPECT(p_2_14 != NULL);
  141. EXPECT(p_fin != NULL);
  142. if ((pinseq != NULL) && (p_8_9 != NULL) && (p_4_8 != NULL) && (p_4_10 != NULL) && (p_2_14 != NULL) && (p_fin != NULL)) {
  143. /* pass the segment to tcp_input */
  144. tcp_input(p_8_9, &netif);
  145. /* check if counters are as expected */
  146. EXPECT(counters.close_calls == 0);
  147. EXPECT(counters.recv_calls == 0);
  148. EXPECT(counters.recved_bytes == 0);
  149. EXPECT(counters.err_calls == 0);
  150. /* check ooseq queue */
  151. EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
  152. EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 8);
  153. EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 9); /* includes FIN */
  154. /* pass the segment to tcp_input */
  155. tcp_input(p_4_8, &netif);
  156. /* check if counters are as expected */
  157. EXPECT(counters.close_calls == 0);
  158. EXPECT(counters.recv_calls == 0);
  159. EXPECT(counters.recved_bytes == 0);
  160. EXPECT(counters.err_calls == 0);
  161. /* check ooseq queue */
  162. EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
  163. EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4);
  164. EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4);
  165. EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
  166. EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
  167. /* pass the segment to tcp_input */
  168. tcp_input(p_4_10, &netif);
  169. /* check if counters are as expected */
  170. EXPECT(counters.close_calls == 0);
  171. EXPECT(counters.recv_calls == 0);
  172. EXPECT(counters.recved_bytes == 0);
  173. EXPECT(counters.err_calls == 0);
  174. /* ooseq queue: unchanged */
  175. EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
  176. EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4);
  177. EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4);
  178. EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
  179. EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
  180. /* pass the segment to tcp_input */
  181. tcp_input(p_2_14, &netif);
  182. /* check if counters are as expected */
  183. EXPECT(counters.close_calls == 0);
  184. EXPECT(counters.recv_calls == 0);
  185. EXPECT(counters.recved_bytes == 0);
  186. EXPECT(counters.err_calls == 0);
  187. /* check ooseq queue */
  188. EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
  189. EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
  190. EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 6);
  191. EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
  192. EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
  193. /* pass the segment to tcp_input */
  194. tcp_input(p_fin, &netif);
  195. /* check if counters are as expected */
  196. EXPECT(counters.close_calls == 0);
  197. EXPECT(counters.recv_calls == 0);
  198. EXPECT(counters.recved_bytes == 0);
  199. EXPECT(counters.err_calls == 0);
  200. /* ooseq queue: unchanged */
  201. EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
  202. EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
  203. EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 6);
  204. EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
  205. EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
  206. /* pass the segment to tcp_input */
  207. tcp_input(pinseq, &netif);
  208. /* check if counters are as expected */
  209. EXPECT(counters.close_calls == 1);
  210. EXPECT(counters.recv_calls == 1);
  211. EXPECT(counters.recved_bytes == data_len);
  212. EXPECT(counters.err_calls == 0);
  213. EXPECT(pcb->ooseq == NULL);
  214. }
  215. /* make sure the pcb is freed */
  216. EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
  217. tcp_abort(pcb);
  218. EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
  219. }
  220. END_TEST
  221. /** create multiple segments and pass them to tcp_input in a wrong
  222. * order to see if ooseq-caching works correctly
  223. * FIN is received IN-SEQUENCE at the end */
  224. START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
  225. {
  226. struct test_tcp_counters counters;
  227. struct tcp_pcb* pcb;
  228. struct pbuf *p_1_2, *p_4_8, *p_3_11, *p_2_12, *p_15_1, *p_15_1a, *pinseq, *pinseqFIN;
  229. char data[] = {
  230. 1, 2, 3, 4,
  231. 5, 6, 7, 8,
  232. 9, 10, 11, 12,
  233. 13, 14, 15, 16};
  234. struct ip_addr remote_ip, local_ip;
  235. u16_t data_len;
  236. u16_t remote_port = 0x100, local_port = 0x101;
  237. struct netif netif;
  238. LWIP_UNUSED_ARG(_i);
  239. /* initialize local vars */
  240. memset(&netif, 0, sizeof(netif));
  241. IP4_ADDR(&local_ip, 192, 168, 1, 1);
  242. IP4_ADDR(&remote_ip, 192, 168, 1, 2);
  243. data_len = sizeof(data);
  244. /* initialize counter struct */
  245. memset(&counters, 0, sizeof(counters));
  246. counters.expected_data_len = data_len;
  247. counters.expected_data = data;
  248. /* create and initialize the pcb */
  249. pcb = test_tcp_new_counters_pcb(&counters);
  250. EXPECT_RET(pcb != NULL);
  251. tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
  252. /* create segments */
  253. /* p1: 7 bytes - 2 before FIN */
  254. /* seqno: 1..2 */
  255. p_1_2 = tcp_create_rx_segment(pcb, &data[1], 2, 1, 0, TCP_ACK);
  256. /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */
  257. /* seqno: 4..11 */
  258. p_4_8 = tcp_create_rx_segment(pcb, &data[4], 8, 4, 0, TCP_ACK);
  259. /* p3: same as p2 but 2 bytes longer and one byte more at the front */
  260. /* seqno: 3..13 */
  261. p_3_11 = tcp_create_rx_segment(pcb, &data[3], 11, 3, 0, TCP_ACK);
  262. /* p4: 13 bytes - 2 before FIN - should be ignored as contained in p1 and p3 */
  263. /* seqno: 2..13 */
  264. p_2_12 = tcp_create_rx_segment(pcb, &data[2], 12, 2, 0, TCP_ACK);
  265. /* pinseq is the first segment that is held back to create ooseq! */
  266. /* seqno: 0..3 */
  267. pinseq = tcp_create_rx_segment(pcb, &data[0], 4, 0, 0, TCP_ACK);
  268. /* p5: last byte before FIN */
  269. /* seqno: 15 */
  270. p_15_1 = tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK);
  271. /* p6: same as p5, should be ignored */
  272. p_15_1a= tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK);
  273. /* pinseqFIN: last 2 bytes plus FIN */
  274. /* only segment containing seqno 14 and FIN */
  275. pinseqFIN = tcp_create_rx_segment(pcb, &data[14], 2, 14, 0, TCP_ACK|TCP_FIN);
  276. EXPECT(pinseq != NULL);
  277. EXPECT(p_1_2 != NULL);
  278. EXPECT(p_4_8 != NULL);
  279. EXPECT(p_3_11 != NULL);
  280. EXPECT(p_2_12 != NULL);
  281. EXPECT(p_15_1 != NULL);
  282. EXPECT(p_15_1a != NULL);
  283. EXPECT(pinseqFIN != NULL);
  284. if ((pinseq != NULL) && (p_1_2 != NULL) && (p_4_8 != NULL) && (p_3_11 != NULL) && (p_2_12 != NULL)
  285. && (p_15_1 != NULL) && (p_15_1a != NULL) && (pinseqFIN != NULL)) {
  286. /* pass the segment to tcp_input */
  287. tcp_input(p_1_2, &netif);
  288. /* check if counters are as expected */
  289. EXPECT(counters.close_calls == 0);
  290. EXPECT(counters.recv_calls == 0);
  291. EXPECT(counters.recved_bytes == 0);
  292. EXPECT(counters.err_calls == 0);
  293. /* check ooseq queue */
  294. EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
  295. EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
  296. EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
  297. /* pass the segment to tcp_input */
  298. tcp_input(p_4_8, &netif);
  299. /* check if counters are as expected */
  300. EXPECT(counters.close_calls == 0);
  301. EXPECT(counters.recv_calls == 0);
  302. EXPECT(counters.recved_bytes == 0);
  303. EXPECT(counters.err_calls == 0);
  304. /* check ooseq queue */
  305. EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
  306. EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
  307. EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
  308. EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 4);
  309. EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 8);
  310. /* pass the segment to tcp_input */
  311. tcp_input(p_3_11, &netif);
  312. /* check if counters are as expected */
  313. EXPECT(counters.close_calls == 0);
  314. EXPECT(counters.recv_calls == 0);
  315. EXPECT(counters.recved_bytes == 0);
  316. EXPECT(counters.err_calls == 0);
  317. /* check ooseq queue */
  318. EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
  319. EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
  320. EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
  321. /* p_3_11 has removed p_4_8 from ooseq */
  322. EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 3);
  323. EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 11);
  324. /* pass the segment to tcp_input */
  325. tcp_input(p_2_12, &netif);
  326. /* check if counters are as expected */
  327. EXPECT(counters.close_calls == 0);
  328. EXPECT(counters.recv_calls == 0);
  329. EXPECT(counters.recved_bytes == 0);
  330. EXPECT(counters.err_calls == 0);
  331. /* check ooseq queue */
  332. EXPECT_OOSEQ(tcp_oos_count(pcb) == 3);
  333. EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
  334. EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
  335. EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 2);
  336. EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 1);
  337. EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 2) == 3);
  338. EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 2) == 11);
  339. /* pass the segment to tcp_input */
  340. tcp_input(pinseq, &netif);
  341. /* check if counters are as expected */
  342. EXPECT(counters.close_calls == 0);
  343. EXPECT(counters.recv_calls == 1);
  344. EXPECT(counters.recved_bytes == 14);
  345. EXPECT(counters.err_calls == 0);
  346. EXPECT(pcb->ooseq == NULL);
  347. /* pass the segment to tcp_input */
  348. tcp_input(p_15_1, &netif);
  349. /* check if counters are as expected */
  350. EXPECT(counters.close_calls == 0);
  351. EXPECT(counters.recv_calls == 1);
  352. EXPECT(counters.recved_bytes == 14);
  353. EXPECT(counters.err_calls == 0);
  354. /* check ooseq queue */
  355. EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
  356. EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15);
  357. EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
  358. /* pass the segment to tcp_input */
  359. tcp_input(p_15_1a, &netif);
  360. /* check if counters are as expected */
  361. EXPECT(counters.close_calls == 0);
  362. EXPECT(counters.recv_calls == 1);
  363. EXPECT(counters.recved_bytes == 14);
  364. EXPECT(counters.err_calls == 0);
  365. /* check ooseq queue: unchanged */
  366. EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
  367. EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15);
  368. EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
  369. /* pass the segment to tcp_input */
  370. tcp_input(pinseqFIN, &netif);
  371. /* check if counters are as expected */
  372. EXPECT(counters.close_calls == 1);
  373. EXPECT(counters.recv_calls == 2);
  374. EXPECT(counters.recved_bytes == data_len);
  375. EXPECT(counters.err_calls == 0);
  376. EXPECT(pcb->ooseq == NULL);
  377. }
  378. /* make sure the pcb is freed */
  379. EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
  380. tcp_abort(pcb);
  381. EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
  382. }
  383. END_TEST
  384. /** Create the suite including all tests for this module */
  385. Suite *
  386. tcp_oos_suite(void)
  387. {
  388. TFun tests[] = {
  389. test_tcp_recv_ooseq_FIN_OOSEQ,
  390. test_tcp_recv_ooseq_FIN_INSEQ,
  391. };
  392. return create_suite("TCP_OOS", tests, sizeof(tests)/sizeof(TFun), tcp_oos_setup, tcp_oos_teardown);
  393. }