3 #include "lwip/tcp_impl.h"
4 #include "lwip/stats.h"
5 #include "tcp_helper.h"
7 #if !LWIP_STATS || !TCP_STATS || !MEMP_STATS
8 #error "This tests needs TCP- and MEMP-statistics enabled"
11 /* Setups/teardown functions */
29 /** Call tcp_new() and tcp_abort() and test memp stats */
30 START_TEST(test_tcp_new_abort)
35 fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
38 fail_unless(pcb != NULL);
40 fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
42 fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
47 /** Create an ESTABLISHED pcb and check if receive callback is called */
48 START_TEST(test_tcp_recv_inseq)
50 struct test_tcp_counters counters;
53 char data[] = {1, 2, 3, 4};
54 ip_addr_t remote_ip, local_ip;
56 u16_t remote_port = 0x100, local_port = 0x101;
60 /* initialize local vars */
61 memset(&netif, 0, sizeof(netif));
62 IP4_ADDR(&local_ip, 192, 168, 1, 1);
63 IP4_ADDR(&remote_ip, 192, 168, 1, 2);
64 data_len = sizeof(data);
65 /* initialize counter struct */
66 memset(&counters, 0, sizeof(counters));
67 counters.expected_data_len = data_len;
68 counters.expected_data = data;
70 /* create and initialize the pcb */
71 pcb = test_tcp_new_counters_pcb(&counters);
72 EXPECT_RET(pcb != NULL);
73 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
75 /* create a segment */
76 p = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0);
79 /* pass the segment to tcp_input */
80 test_tcp_input(p, &netif);
81 /* check if counters are as expected */
82 EXPECT(counters.close_calls == 0);
83 EXPECT(counters.recv_calls == 1);
84 EXPECT(counters.recved_bytes == data_len);
85 EXPECT(counters.err_calls == 0);
88 /* make sure the pcb is freed */
89 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
91 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
95 /** Provoke fast retransmission by duplicate ACKs and then recover by ACKing all sent data.
96 * At the end, send more data. */
97 START_TEST(test_tcp_fast_retx_recover)
100 struct test_tcp_txcounters txcounters;
101 struct test_tcp_counters counters;
104 char data1[] = { 1, 2, 3, 4};
105 char data2[] = { 5, 6, 7, 8};
106 char data3[] = { 9, 10, 11, 12};
107 char data4[] = {13, 14, 15, 16};
108 char data5[] = {17, 18, 19, 20};
109 char data6[] = {21, 22, 23, 24};
110 ip_addr_t remote_ip, local_ip, netmask;
111 u16_t remote_port = 0x100, local_port = 0x101;
115 /* initialize local vars */
116 IP4_ADDR(&local_ip, 192, 168, 1, 1);
117 IP4_ADDR(&remote_ip, 192, 168, 1, 2);
118 IP4_ADDR(&netmask, 255, 255, 255, 0);
119 test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask);
120 memset(&counters, 0, sizeof(counters));
122 /* create and initialize the pcb */
123 pcb = test_tcp_new_counters_pcb(&counters);
124 EXPECT_RET(pcb != NULL);
125 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
127 /* disable initial congestion window (we don't send a SYN here...) */
128 pcb->cwnd = pcb->snd_wnd;
129 //tcp_nagle_disable(pcb);
132 err = tcp_write(pcb, data1, sizeof(data1), TCP_WRITE_FLAG_COPY);
133 EXPECT_RET(err == ERR_OK);
134 err = tcp_output(pcb);
135 EXPECT_RET(err == ERR_OK);
136 EXPECT_RET(txcounters.num_tx_calls == 1);
137 EXPECT_RET(txcounters.num_tx_bytes == sizeof(data1) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
138 memset(&txcounters, 0, sizeof(txcounters));
139 /* "recv" ACK for data1 */
140 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 4, TCP_ACK);
141 EXPECT_RET(p != NULL);
142 test_tcp_input(p, &netif);
143 EXPECT_RET(txcounters.num_tx_calls == 0);
144 EXPECT_RET(pcb->unacked == NULL);
146 err = tcp_write(pcb, data2, sizeof(data2), TCP_WRITE_FLAG_COPY);
147 EXPECT_RET(err == ERR_OK);
148 err = tcp_output(pcb);
149 EXPECT_RET(err == ERR_OK);
150 EXPECT_RET(txcounters.num_tx_calls == 1);
151 EXPECT_RET(txcounters.num_tx_bytes == sizeof(data2) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
152 memset(&txcounters, 0, sizeof(txcounters));
153 /* duplicate ACK for data1 (data2 is lost) */
154 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
155 EXPECT_RET(p != NULL);
156 test_tcp_input(p, &netif);
157 EXPECT_RET(txcounters.num_tx_calls == 0);
158 EXPECT_RET(pcb->dupacks == 1);
160 err = tcp_write(pcb, data3, sizeof(data3), TCP_WRITE_FLAG_COPY);
161 EXPECT_RET(err == ERR_OK);
162 err = tcp_output(pcb);
163 EXPECT_RET(err == ERR_OK);
164 /* nagle enabled, no tx calls */
165 EXPECT_RET(txcounters.num_tx_calls == 0);
166 EXPECT_RET(txcounters.num_tx_bytes == 0);
167 memset(&txcounters, 0, sizeof(txcounters));
168 /* 2nd duplicate ACK for data1 (data2 and data3 are lost) */
169 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
170 EXPECT_RET(p != NULL);
171 test_tcp_input(p, &netif);
172 EXPECT_RET(txcounters.num_tx_calls == 0);
173 EXPECT_RET(pcb->dupacks == 2);
174 /* queue data4, don't send it (unsent-oversize is != 0) */
175 err = tcp_write(pcb, data4, sizeof(data4), TCP_WRITE_FLAG_COPY);
176 EXPECT_RET(err == ERR_OK);
177 /* 3nd duplicate ACK for data1 (data2 and data3 are lost) -> fast retransmission */
178 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
179 EXPECT_RET(p != NULL);
180 test_tcp_input(p, &netif);
181 //EXPECT_RET(txcounters.num_tx_calls == 1);
182 EXPECT_RET(pcb->dupacks == 3);
183 memset(&txcounters, 0, sizeof(txcounters));
184 // TODO: check expected data?
186 /* send data5, not output yet */
187 err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
188 EXPECT_RET(err == ERR_OK);
189 //err = tcp_output(pcb);
190 //EXPECT_RET(err == ERR_OK);
191 EXPECT_RET(txcounters.num_tx_calls == 0);
192 EXPECT_RET(txcounters.num_tx_bytes == 0);
193 memset(&txcounters, 0, sizeof(txcounters));
198 err = tcp_write(pcb, data6, TCP_MSS, TCP_WRITE_FLAG_COPY);
200 }while(err == ERR_OK);
201 EXPECT_RET(err != ERR_OK);
203 err = tcp_output(pcb);
204 EXPECT_RET(err == ERR_OK);
205 //EXPECT_RET(txcounters.num_tx_calls == 0);
206 //EXPECT_RET(txcounters.num_tx_bytes == 0);
207 memset(&txcounters, 0, sizeof(txcounters));
209 /* send even more data */
210 err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
211 EXPECT_RET(err == ERR_OK);
212 err = tcp_output(pcb);
213 EXPECT_RET(err == ERR_OK);
214 /* ...and even more data */
215 err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
216 EXPECT_RET(err == ERR_OK);
217 err = tcp_output(pcb);
218 EXPECT_RET(err == ERR_OK);
219 /* ...and even more data */
220 err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
221 EXPECT_RET(err == ERR_OK);
222 err = tcp_output(pcb);
223 EXPECT_RET(err == ERR_OK);
224 /* ...and even more data */
225 err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
226 EXPECT_RET(err == ERR_OK);
227 err = tcp_output(pcb);
228 EXPECT_RET(err == ERR_OK);
230 /* send ACKs for data2 and data3 */
231 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 12, TCP_ACK);
232 EXPECT_RET(p != NULL);
233 test_tcp_input(p, &netif);
234 //EXPECT_RET(txcounters.num_tx_calls == 0);
236 /* ...and even more data */
237 err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
238 EXPECT_RET(err == ERR_OK);
239 err = tcp_output(pcb);
240 EXPECT_RET(err == ERR_OK);
241 /* ...and even more data */
242 err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
243 EXPECT_RET(err == ERR_OK);
244 err = tcp_output(pcb);
245 EXPECT_RET(err == ERR_OK);
248 /* create expected segment */
249 p1 = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0);
250 EXPECT_RET(p != NULL);
252 /* pass the segment to tcp_input */
253 test_tcp_input(p, &netif);
254 /* check if counters are as expected */
255 EXPECT_RET(counters.close_calls == 0);
256 EXPECT_RET(counters.recv_calls == 1);
257 EXPECT_RET(counters.recved_bytes == data_len);
258 EXPECT_RET(counters.err_calls == 0);
261 /* make sure the pcb is freed */
262 EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
264 EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
269 /** Create the suite including all tests for this module */
276 test_tcp_fast_retx_recover
278 return create_suite("TCP", tests, sizeof(tests)/sizeof(TFun), tcp_setup, tcp_teardown);