ReactOS  0.4.14-dev-376-gaedba84
test_tcp.c File Reference
#include "test_tcp.h"
#include "lwip/tcp_impl.h"
#include "lwip/stats.h"
#include "tcp_helper.h"
Include dependency graph for test_tcp.c:

Go to the source code of this file.

Macros

#define SEQNO1   (0xFFFFFF00 - TCP_MSS)
 
#define ISS   6510
 
#define SEQNO1   (0xFFFFFF00 - TCP_MSS)
 
#define ISS   6510
 

Functions

static void test_tcp_tmr (void)
 
static void tcp_setup (void)
 
static void tcp_teardown (void)
 
 START_TEST (test_tcp_new_abort)
 
END_TEST START_TEST (test_tcp_recv_inseq)
 
END_TEST START_TEST (test_tcp_fast_retx_recover)
 
static void check_seqnos (struct tcp_seg *segs, int num_expected, u32_t *seqnos_expected)
 
 START_TEST (test_tcp_fast_rexmit_wraparound)
 
END_TEST START_TEST (test_tcp_rto_rexmit_wraparound)
 
static END_TEST void test_tcp_tx_full_window_lost (u8_t zero_window_probe_from_unsent)
 
 START_TEST (test_tcp_tx_full_window_lost_from_unsent)
 
END_TEST START_TEST (test_tcp_tx_full_window_lost_from_unacked)
 
END_TEST Suite * tcp_suite (void)
 

Variables

static u8_t test_tcp_timer
 
static END_TEST u8_t tx_data [TCP_WND *2]
 

Macro Definition Documentation

◆ ISS [1/2]

#define ISS   6510

◆ ISS [2/2]

#define ISS   6510

◆ SEQNO1 [1/2]

#define SEQNO1   (0xFFFFFF00 - TCP_MSS)

◆ SEQNO1 [2/2]

#define SEQNO1   (0xFFFFFF00 - TCP_MSS)

Function Documentation

◆ check_seqnos()

static void check_seqnos ( struct tcp_seg *  segs,
int  num_expected,
u32_t seqnos_expected 
)
static

Definition at line 300 of file test_tcp.c.

301 {
302  struct tcp_seg *s = segs;
303  int i;
304  for (i = 0; i < num_expected; i++, s = s->next) {
305  EXPECT_RET(s != NULL);
306  EXPECT(s->tcphdr->seqno == htonl(seqnos_expected[i]));
307  }
308  EXPECT(s == NULL);
309 }
#define htonl(x)
Definition: module.h:212
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define EXPECT_RET(x)
Definition: lwip_check.h:12
smooth NULL
Definition: ftsmooth.c:416
GLdouble s
Definition: gl.h:2039
#define EXPECT(a, b, c, d, e, f)
Definition: vartest.c:1303

Referenced by START_TEST().

◆ START_TEST() [1/7]

START_TEST ( test_tcp_new_abort  )

Call tcp_new() and tcp_abort() and test memp stats

Definition at line 57 of file test_tcp.c.

58 {
59  struct tcp_pcb* pcb;
60  LWIP_UNUSED_ARG(_i);
61 
62  fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
63 
64  pcb = tcp_new();
65  fail_unless(pcb != NULL);
66  if (pcb != NULL) {
67  fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
68  tcp_abort(pcb);
69  fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
70  }
71 }
smooth NULL
Definition: ftsmooth.c:416
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:73

◆ START_TEST() [2/7]

END_TEST START_TEST ( test_tcp_recv_inseq  )

Create an ESTABLISHED pcb and check if receive callback is called

Definition at line 75 of file test_tcp.c.

76 {
78  struct tcp_pcb* pcb;
79  struct pbuf* p;
80  char data[] = {1, 2, 3, 4};
81  ip_addr_t remote_ip, local_ip, netmask;
82  u16_t data_len;
83  u16_t remote_port = 0x100, local_port = 0x101;
84  struct netif netif;
85  struct test_tcp_txcounters txcounters;
86  LWIP_UNUSED_ARG(_i);
87 
88  /* initialize local vars */
89  memset(&netif, 0, sizeof(netif));
90  IP4_ADDR(&local_ip, 192, 168, 1, 1);
91  IP4_ADDR(&remote_ip, 192, 168, 1, 2);
92  IP4_ADDR(&netmask, 255, 255, 255, 0);
93  test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask);
94  data_len = sizeof(data);
95  /* initialize counter struct */
96  memset(&counters, 0, sizeof(counters));
97  counters.expected_data_len = data_len;
98  counters.expected_data = data;
99 
100  /* create and initialize the pcb */
102  EXPECT_RET(pcb != NULL);
103  tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
104 
105  /* create a segment */
106  p = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0);
107  EXPECT(p != NULL);
108  if (p != NULL) {
109  /* pass the segment to tcp_input */
111  /* check if counters are as expected */
112  EXPECT(counters.close_calls == 0);
113  EXPECT(counters.recv_calls == 1);
114  EXPECT(counters.recved_bytes == data_len);
115  EXPECT(counters.err_calls == 0);
116  }
117 
118  /* make sure the pcb is freed */
119  EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
120  tcp_abort(pcb);
121  EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
122 }
struct tcp_pcb * test_tcp_new_counters_pcb(struct test_tcp_counters *counters)
Definition: tcp_helper.c:223
void test_tcp_init_netif(struct netif *netif, struct test_tcp_txcounters *txcounters, ip_addr_t *ip_addr, ip_addr_t *netmask)
Definition: tcp_helper.c:283
GLint GLint GLsizei GLuint * counters
Definition: glext.h:11114
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
Definition: ip_addr.h:64
static __inline void tcp_set_state(struct sock *sk, int state)
Definition: tcpcore.h:3280
#define IP4_ADDR(ipaddr, a, b, c, d)
Definition: ip_addr.h:139
#define EXPECT_RET(x)
Definition: lwip_check.h:12
smooth NULL
Definition: ftsmooth.c:416
Definition: pbuf.h:79
void test_tcp_input(struct pbuf *p, struct netif *inp)
Definition: tcp_helper.c:238
struct pbuf * tcp_create_rx_segment(struct tcp_pcb *pcb, void *data, size_t data_len, u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags)
Definition: tcp_helper.c:118
Definition: netif.h:136
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
unsigned short u16_t
Definition: cc.h:24
#define EXPECT(a, b, c, d, e, f)
Definition: vartest.c:1303
GLfloat GLfloat p
Definition: glext.h:8902
#define memset(x, y, z)
Definition: compat.h:39
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:73

◆ START_TEST() [3/7]

END_TEST START_TEST ( test_tcp_fast_retx_recover  )

Provoke fast retransmission by duplicate ACKs and then recover by ACKing all sent data. At the end, send more data.

Definition at line 127 of file test_tcp.c.

128 {
129  struct netif netif;
130  struct test_tcp_txcounters txcounters;
132  struct tcp_pcb* pcb;
133  struct pbuf* p;
134  char data1[] = { 1, 2, 3, 4};
135  char data2[] = { 5, 6, 7, 8};
136  char data3[] = { 9, 10, 11, 12};
137  char data4[] = {13, 14, 15, 16};
138  char data5[] = {17, 18, 19, 20};
139  char data6[] = {21, 22, 23, 24};
140  ip_addr_t remote_ip, local_ip, netmask;
141  u16_t remote_port = 0x100, local_port = 0x101;
142  err_t err;
143  LWIP_UNUSED_ARG(_i);
144 
145  /* initialize local vars */
146  IP4_ADDR(&local_ip, 192, 168, 1, 1);
147  IP4_ADDR(&remote_ip, 192, 168, 1, 2);
148  IP4_ADDR(&netmask, 255, 255, 255, 0);
149  test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask);
150  memset(&counters, 0, sizeof(counters));
151 
152  /* create and initialize the pcb */
154  EXPECT_RET(pcb != NULL);
155  tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
156  pcb->mss = TCP_MSS;
157  /* disable initial congestion window (we don't send a SYN here...) */
158  pcb->cwnd = pcb->snd_wnd;
159 
160  /* send data1 */
161  err = tcp_write(pcb, data1, sizeof(data1), TCP_WRITE_FLAG_COPY);
162  EXPECT_RET(err == ERR_OK);
163  err = tcp_output(pcb);
164  EXPECT_RET(err == ERR_OK);
165  EXPECT_RET(txcounters.num_tx_calls == 1);
166  EXPECT_RET(txcounters.num_tx_bytes == sizeof(data1) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
167  memset(&txcounters, 0, sizeof(txcounters));
168  /* "recv" ACK for data1 */
169  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 4, TCP_ACK);
170  EXPECT_RET(p != NULL);
172  EXPECT_RET(txcounters.num_tx_calls == 0);
173  EXPECT_RET(pcb->unacked == NULL);
174  /* send data2 */
175  err = tcp_write(pcb, data2, sizeof(data2), TCP_WRITE_FLAG_COPY);
176  EXPECT_RET(err == ERR_OK);
177  err = tcp_output(pcb);
178  EXPECT_RET(err == ERR_OK);
179  EXPECT_RET(txcounters.num_tx_calls == 1);
180  EXPECT_RET(txcounters.num_tx_bytes == sizeof(data2) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
181  memset(&txcounters, 0, sizeof(txcounters));
182  /* duplicate ACK for data1 (data2 is lost) */
183  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
184  EXPECT_RET(p != NULL);
186  EXPECT_RET(txcounters.num_tx_calls == 0);
187  EXPECT_RET(pcb->dupacks == 1);
188  /* send data3 */
189  err = tcp_write(pcb, data3, sizeof(data3), TCP_WRITE_FLAG_COPY);
190  EXPECT_RET(err == ERR_OK);
191  err = tcp_output(pcb);
192  EXPECT_RET(err == ERR_OK);
193  /* nagle enabled, no tx calls */
194  EXPECT_RET(txcounters.num_tx_calls == 0);
195  EXPECT_RET(txcounters.num_tx_bytes == 0);
196  memset(&txcounters, 0, sizeof(txcounters));
197  /* 2nd duplicate ACK for data1 (data2 and data3 are lost) */
198  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
199  EXPECT_RET(p != NULL);
201  EXPECT_RET(txcounters.num_tx_calls == 0);
202  EXPECT_RET(pcb->dupacks == 2);
203  /* queue data4, don't send it (unsent-oversize is != 0) */
204  err = tcp_write(pcb, data4, sizeof(data4), TCP_WRITE_FLAG_COPY);
205  EXPECT_RET(err == ERR_OK);
206  /* 3nd duplicate ACK for data1 (data2 and data3 are lost) -> fast retransmission */
207  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
208  EXPECT_RET(p != NULL);
210  /*EXPECT_RET(txcounters.num_tx_calls == 1);*/
211  EXPECT_RET(pcb->dupacks == 3);
212  memset(&txcounters, 0, sizeof(txcounters));
213  /* TODO: check expected data?*/
214 
215  /* send data5, not output yet */
216  err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
217  EXPECT_RET(err == ERR_OK);
218  /*err = tcp_output(pcb);
219  EXPECT_RET(err == ERR_OK);*/
220  EXPECT_RET(txcounters.num_tx_calls == 0);
221  EXPECT_RET(txcounters.num_tx_bytes == 0);
222  memset(&txcounters, 0, sizeof(txcounters));
223  {
224  int i = 0;
225  do
226  {
227  err = tcp_write(pcb, data6, TCP_MSS, TCP_WRITE_FLAG_COPY);
228  i++;
229  }while(err == ERR_OK);
230  EXPECT_RET(err != ERR_OK);
231  }
232  err = tcp_output(pcb);
233  EXPECT_RET(err == ERR_OK);
234  /*EXPECT_RET(txcounters.num_tx_calls == 0);
235  EXPECT_RET(txcounters.num_tx_bytes == 0);*/
236  memset(&txcounters, 0, sizeof(txcounters));
237 
238  /* send even more data */
239  err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
240  EXPECT_RET(err == ERR_OK);
241  err = tcp_output(pcb);
242  EXPECT_RET(err == ERR_OK);
243  /* ...and even more data */
244  err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
245  EXPECT_RET(err == ERR_OK);
246  err = tcp_output(pcb);
247  EXPECT_RET(err == ERR_OK);
248  /* ...and even more data */
249  err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
250  EXPECT_RET(err == ERR_OK);
251  err = tcp_output(pcb);
252  EXPECT_RET(err == ERR_OK);
253  /* ...and even more data */
254  err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
255  EXPECT_RET(err == ERR_OK);
256  err = tcp_output(pcb);
257  EXPECT_RET(err == ERR_OK);
258 
259  /* send ACKs for data2 and data3 */
260  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 12, TCP_ACK);
261  EXPECT_RET(p != NULL);
263  /*EXPECT_RET(txcounters.num_tx_calls == 0);*/
264 
265  /* ...and even more data */
266  err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
267  EXPECT_RET(err == ERR_OK);
268  err = tcp_output(pcb);
269  EXPECT_RET(err == ERR_OK);
270  /* ...and even more data */
271  err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
272  EXPECT_RET(err == ERR_OK);
273  err = tcp_output(pcb);
274  EXPECT_RET(err == ERR_OK);
275 
276 #if 0
277  /* create expected segment */
278  p1 = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0);
279  EXPECT_RET(p != NULL);
280  if (p != NULL) {
281  /* pass the segment to tcp_input */
283  /* check if counters are as expected */
284  EXPECT_RET(counters.close_calls == 0);
285  EXPECT_RET(counters.recv_calls == 1);
286  EXPECT_RET(counters.recved_bytes == data_len);
287  EXPECT_RET(counters.err_calls == 0);
288  }
289 #endif
290  /* make sure the pcb is freed */
291  EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
292  tcp_abort(pcb);
293  EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
294 }
static const WCHAR data3[]
Definition: db.c:2979
struct tcp_pcb * test_tcp_new_counters_pcb(struct test_tcp_counters *counters)
Definition: tcp_helper.c:223
void test_tcp_init_netif(struct netif *netif, struct test_tcp_txcounters *txcounters, ip_addr_t *ip_addr, ip_addr_t *netmask)
Definition: tcp_helper.c:283
GLint GLint GLsizei GLuint * counters
Definition: glext.h:11114
Definition: tftpd.h:125
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
Definition: ip_addr.h:64
static const WCHAR data5[]
Definition: db.c:2985
static __inline void tcp_set_state(struct sock *sk, int state)
Definition: tcpcore.h:3280
#define IP4_ADDR(ipaddr, a, b, c, d)
Definition: ip_addr.h:139
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define EXPECT_RET(x)
Definition: lwip_check.h:12
static const char data4[]
Definition: db.c:2983
smooth NULL
Definition: ftsmooth.c:416
s8_t err_t
Definition: err.h:47
#define ERR_OK
Definition: err.h:52
Definition: pbuf.h:79
void test_tcp_input(struct pbuf *p, struct netif *inp)
Definition: tcp_helper.c:238
struct pbuf * tcp_create_rx_segment(struct tcp_pcb *pcb, void *data, size_t data_len, u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags)
Definition: tcp_helper.c:118
Definition: netif.h:136
#define err(...)
Definition: ip.h:116
#define TCP_MSS
Definition: opt.h:956
unsigned short u16_t
Definition: cc.h:24
static const WCHAR data6[]
Definition: db.c:3003
GLfloat GLfloat p
Definition: glext.h:8902
#define memset(x, y, z)
Definition: compat.h:39
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:73
Definition: tftpd.h:137

◆ START_TEST() [4/7]

START_TEST ( test_tcp_fast_rexmit_wraparound  )

Send data with sequence numbers that wrap around the u32_t range. Then, provoke fast retransmission by duplicate ACKs and check that all segment lists are still properly sorted.

Definition at line 314 of file test_tcp.c.

315 {
316  struct netif netif;
317  struct test_tcp_txcounters txcounters;
319  struct tcp_pcb* pcb;
320  struct pbuf* p;
321  ip_addr_t remote_ip, local_ip, netmask;
322  u16_t remote_port = 0x100, local_port = 0x101;
323  err_t err;
324 #define SEQNO1 (0xFFFFFF00 - TCP_MSS)
325 #define ISS 6510
326  u16_t i, sent_total = 0;
327  u32_t seqnos[] = {
328  SEQNO1,
329  SEQNO1 + (1 * TCP_MSS),
330  SEQNO1 + (2 * TCP_MSS),
331  SEQNO1 + (3 * TCP_MSS),
332  SEQNO1 + (4 * TCP_MSS),
333  SEQNO1 + (5 * TCP_MSS)};
334  LWIP_UNUSED_ARG(_i);
335 
336  for (i = 0; i < sizeof(tx_data); i++) {
337  tx_data[i] = (u8_t)i;
338  }
339 
340  /* initialize local vars */
341  IP4_ADDR(&local_ip, 192, 168, 1, 1);
342  IP4_ADDR(&remote_ip, 192, 168, 1, 2);
343  IP4_ADDR(&netmask, 255, 255, 255, 0);
344  test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask);
345  memset(&counters, 0, sizeof(counters));
346 
347  /* create and initialize the pcb */
348  tcp_ticks = SEQNO1 - ISS;
350  EXPECT_RET(pcb != NULL);
351  EXPECT(pcb->lastack == SEQNO1);
352  tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
353  pcb->mss = TCP_MSS;
354  /* disable initial congestion window (we don't send a SYN here...) */
355  pcb->cwnd = 2*TCP_MSS;
356 
357  /* send 6 mss-sized segments */
358  for (i = 0; i < 6; i++) {
359  err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
360  EXPECT_RET(err == ERR_OK);
361  sent_total += TCP_MSS;
362  }
363  check_seqnos(pcb->unsent, 6, seqnos);
364  EXPECT(pcb->unacked == NULL);
365  err = tcp_output(pcb);
366  EXPECT(txcounters.num_tx_calls == 2);
367  EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U));
368  memset(&txcounters, 0, sizeof(txcounters));
369 
370  check_seqnos(pcb->unacked, 2, seqnos);
371  check_seqnos(pcb->unsent, 4, &seqnos[2]);
372 
373  /* ACK the first segment */
374  p = tcp_create_rx_segment(pcb, NULL, 0, 0, TCP_MSS, TCP_ACK);
376  /* ensure this didn't trigger a retransmission */
377  EXPECT(txcounters.num_tx_calls == 1);
378  EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U);
379  memset(&txcounters, 0, sizeof(txcounters));
380  check_seqnos(pcb->unacked, 2, &seqnos[1]);
381  check_seqnos(pcb->unsent, 3, &seqnos[3]);
382 
383  /* 3 dupacks */
384  EXPECT(pcb->dupacks == 0);
385  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
387  EXPECT(txcounters.num_tx_calls == 0);
388  EXPECT(pcb->dupacks == 1);
389  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
391  EXPECT(txcounters.num_tx_calls == 0);
392  EXPECT(pcb->dupacks == 2);
393  /* 3rd dupack -> fast rexmit */
394  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
396  EXPECT(pcb->dupacks == 3);
397  EXPECT(txcounters.num_tx_calls == 4);
398  memset(&txcounters, 0, sizeof(txcounters));
399  EXPECT(pcb->unsent == NULL);
400  check_seqnos(pcb->unacked, 5, &seqnos[1]);
401 
402  /* make sure the pcb is freed */
403  EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
404  tcp_abort(pcb);
405  EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
406 }
struct tcp_pcb * test_tcp_new_counters_pcb(struct test_tcp_counters *counters)
Definition: tcp_helper.c:223
void test_tcp_init_netif(struct netif *netif, struct test_tcp_txcounters *txcounters, ip_addr_t *ip_addr, ip_addr_t *netmask)
Definition: tcp_helper.c:283
#define SEQNO1
#define U(x)
Definition: wordpad.c:44
GLint GLint GLsizei GLuint * counters
Definition: glext.h:11114
static void check_seqnos(struct tcp_seg *segs, int num_expected, u32_t *seqnos_expected)
Definition: test_tcp.c:300
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
Definition: ip_addr.h:64
static __inline void tcp_set_state(struct sock *sk, int state)
Definition: tcpcore.h:3280
#define IP4_ADDR(ipaddr, a, b, c, d)
Definition: ip_addr.h:139
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define EXPECT_RET(x)
Definition: lwip_check.h:12
smooth NULL
Definition: ftsmooth.c:416
s8_t err_t
Definition: err.h:47
#define ISS
static END_TEST u8_t tx_data[TCP_WND *2]
Definition: test_tcp.c:297
#define ERR_OK
Definition: err.h:52
Definition: pbuf.h:79
unsigned long u32_t
Definition: cc.h:25
void test_tcp_input(struct pbuf *p, struct netif *inp)
Definition: tcp_helper.c:238
struct pbuf * tcp_create_rx_segment(struct tcp_pcb *pcb, void *data, size_t data_len, u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags)
Definition: tcp_helper.c:118
Definition: netif.h:136
#define err(...)
unsigned char u8_t
Definition: cc.h:23
#define TCP_MSS
Definition: opt.h:956
unsigned short u16_t
Definition: cc.h:24
#define EXPECT(a, b, c, d, e, f)
Definition: vartest.c:1303
GLfloat GLfloat p
Definition: glext.h:8902
#define memset(x, y, z)
Definition: compat.h:39
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:73

◆ START_TEST() [5/7]

END_TEST START_TEST ( test_tcp_rto_rexmit_wraparound  )

Send data with sequence numbers that wrap around the u32_t range. Then, provoke RTO retransmission and check that all segment lists are still properly sorted.

Definition at line 412 of file test_tcp.c.

413 {
414  struct netif netif;
415  struct test_tcp_txcounters txcounters;
417  struct tcp_pcb* pcb;
418  ip_addr_t remote_ip, local_ip, netmask;
419  u16_t remote_port = 0x100, local_port = 0x101;
420  err_t err;
421 #define SEQNO1 (0xFFFFFF00 - TCP_MSS)
422 #define ISS 6510
423  u16_t i, sent_total = 0;
424  u32_t seqnos[] = {
425  SEQNO1,
426  SEQNO1 + (1 * TCP_MSS),
427  SEQNO1 + (2 * TCP_MSS),
428  SEQNO1 + (3 * TCP_MSS),
429  SEQNO1 + (4 * TCP_MSS),
430  SEQNO1 + (5 * TCP_MSS)};
431  LWIP_UNUSED_ARG(_i);
432 
433  for (i = 0; i < sizeof(tx_data); i++) {
434  tx_data[i] = (u8_t)i;
435  }
436 
437  /* initialize local vars */
438  IP4_ADDR(&local_ip, 192, 168, 1, 1);
439  IP4_ADDR(&remote_ip, 192, 168, 1, 2);
440  IP4_ADDR(&netmask, 255, 255, 255, 0);
441  test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask);
442  memset(&counters, 0, sizeof(counters));
443 
444  /* create and initialize the pcb */
445  tcp_ticks = 0;
446  tcp_ticks = 0 - tcp_next_iss();
447  tcp_ticks = SEQNO1 - tcp_next_iss();
449  EXPECT_RET(pcb != NULL);
450  EXPECT(pcb->lastack == SEQNO1);
451  tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
452  pcb->mss = TCP_MSS;
453  /* disable initial congestion window (we don't send a SYN here...) */
454  pcb->cwnd = 2*TCP_MSS;
455 
456  /* send 6 mss-sized segments */
457  for (i = 0; i < 6; i++) {
458  err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
459  EXPECT_RET(err == ERR_OK);
460  sent_total += TCP_MSS;
461  }
462  check_seqnos(pcb->unsent, 6, seqnos);
463  EXPECT(pcb->unacked == NULL);
464  err = tcp_output(pcb);
465  EXPECT(txcounters.num_tx_calls == 2);
466  EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U));
467  memset(&txcounters, 0, sizeof(txcounters));
468 
469  check_seqnos(pcb->unacked, 2, seqnos);
470  check_seqnos(pcb->unsent, 4, &seqnos[2]);
471 
472  /* call the tcp timer some times */
473  for (i = 0; i < 10; i++) {
474  test_tcp_tmr();
475  EXPECT(txcounters.num_tx_calls == 0);
476  }
477  /* 11th call to tcp_tmr: RTO rexmit fires */
478  test_tcp_tmr();
479  EXPECT(txcounters.num_tx_calls == 1);
480  check_seqnos(pcb->unacked, 1, seqnos);
481  check_seqnos(pcb->unsent, 5, &seqnos[1]);
482 
483  /* fake greater cwnd */
484  pcb->cwnd = pcb->snd_wnd;
485  /* send more data */
486  err = tcp_output(pcb);
487  EXPECT(err == ERR_OK);
488  /* check queues are sorted */
489  EXPECT(pcb->unsent == NULL);
490  check_seqnos(pcb->unacked, 6, seqnos);
491 
492  /* make sure the pcb is freed */
493  EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
494  tcp_abort(pcb);
495  EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
496 }
struct tcp_pcb * test_tcp_new_counters_pcb(struct test_tcp_counters *counters)
Definition: tcp_helper.c:223
void test_tcp_init_netif(struct netif *netif, struct test_tcp_txcounters *txcounters, ip_addr_t *ip_addr, ip_addr_t *netmask)
Definition: tcp_helper.c:283
#define SEQNO1
#define U(x)
Definition: wordpad.c:44
GLint GLint GLsizei GLuint * counters
Definition: glext.h:11114
static void check_seqnos(struct tcp_seg *segs, int num_expected, u32_t *seqnos_expected)
Definition: test_tcp.c:300
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
Definition: ip_addr.h:64
static __inline void tcp_set_state(struct sock *sk, int state)
Definition: tcpcore.h:3280
#define IP4_ADDR(ipaddr, a, b, c, d)
Definition: ip_addr.h:139
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define EXPECT_RET(x)
Definition: lwip_check.h:12
smooth NULL
Definition: ftsmooth.c:416
s8_t err_t
Definition: err.h:47
static END_TEST u8_t tx_data[TCP_WND *2]
Definition: test_tcp.c:297
#define ERR_OK
Definition: err.h:52
unsigned long u32_t
Definition: cc.h:25
Definition: netif.h:136
#define err(...)
unsigned char u8_t
Definition: cc.h:23
#define TCP_MSS
Definition: opt.h:956
unsigned short u16_t
Definition: cc.h:24
#define EXPECT(a, b, c, d, e, f)
Definition: vartest.c:1303
static void test_tcp_tmr(void)
Definition: test_tcp.c:22
#define memset(x, y, z)
Definition: compat.h:39
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:73

◆ START_TEST() [6/7]

START_TEST ( test_tcp_tx_full_window_lost_from_unsent  )

Definition at line 643 of file test_tcp.c.

644 {
645  LWIP_UNUSED_ARG(_i);
647 }
static END_TEST void test_tcp_tx_full_window_lost(u8_t zero_window_probe_from_unsent)
Definition: test_tcp.c:501
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:73

◆ START_TEST() [7/7]

END_TEST START_TEST ( test_tcp_tx_full_window_lost_from_unacked  )

Definition at line 650 of file test_tcp.c.

651 {
652  LWIP_UNUSED_ARG(_i);
654 }
static END_TEST void test_tcp_tx_full_window_lost(u8_t zero_window_probe_from_unsent)
Definition: test_tcp.c:501
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:73

◆ tcp_setup()

static void tcp_setup ( void  )
static

Definition at line 33 of file test_tcp.c.

34 {
35  /* reset iss to default (6510) */
36  tcp_ticks = 0;
37  tcp_ticks = 0 - (tcp_next_iss() - 6510);
38  tcp_next_iss();
39  tcp_ticks = 0;
40 
41  test_tcp_timer = 0;
43 }
void tcp_remove_all(void)
Definition: tcp_helper.c:28
static u8_t test_tcp_timer
Definition: test_tcp.c:18

Referenced by tcp_suite().

◆ tcp_suite()

END_TEST Suite* tcp_suite ( void  )

Create the suite including all tests for this module

Definition at line 659 of file test_tcp.c.

660 {
661  TFun tests[] = {
662  test_tcp_new_abort,
663  test_tcp_recv_inseq,
664  test_tcp_fast_retx_recover,
665  test_tcp_fast_rexmit_wraparound,
666  test_tcp_rto_rexmit_wraparound,
667  test_tcp_tx_full_window_lost_from_unacked,
668  test_tcp_tx_full_window_lost_from_unsent
669  };
670  return create_suite("TCP", tests, sizeof(tests)/sizeof(TFun), tcp_setup, tcp_teardown);
671 }
struct param_test tests[]
static void tcp_teardown(void)
Definition: test_tcp.c:46
static Suite * create_suite(const char *name, TFun *tests, size_t num_tests, SFun setup, SFun teardown)
Definition: lwip_check.h:20
static void tcp_setup(void)
Definition: test_tcp.c:33

Referenced by main().

◆ tcp_teardown()

static void tcp_teardown ( void  )
static

Definition at line 46 of file test_tcp.c.

47 {
49  netif_list = NULL;
51 }
struct netif * netif_list
Definition: netif.c:75
struct netif * netif_default
Definition: netif.c:76
smooth NULL
Definition: ftsmooth.c:416
void tcp_remove_all(void)
Definition: tcp_helper.c:28

Referenced by tcp_suite().

◆ test_tcp_tmr()

static void test_tcp_tmr ( void  )
static

Definition at line 22 of file test_tcp.c.

23 {
24  tcp_fasttmr();
25  if (++test_tcp_timer & 1) {
26  tcp_slowtmr();
27  }
28 }
static u8_t test_tcp_timer
Definition: test_tcp.c:18

Referenced by START_TEST(), and test_tcp_tx_full_window_lost().

◆ test_tcp_tx_full_window_lost()

static END_TEST void test_tcp_tx_full_window_lost ( u8_t  zero_window_probe_from_unsent)
static

Provoke fast retransmission by duplicate ACKs and then recover by ACKing all sent data. At the end, send more data.

Definition at line 501 of file test_tcp.c.

502 {
503  struct netif netif;
504  struct test_tcp_txcounters txcounters;
506  struct tcp_pcb* pcb;
507  struct pbuf *p;
508  ip_addr_t remote_ip, local_ip, netmask;
509  u16_t remote_port = 0x100, local_port = 0x101;
510  err_t err;
511  u16_t sent_total, i;
512  u8_t expected = 0xFE;
513 
514  for (i = 0; i < sizeof(tx_data); i++) {
515  u8_t d = (u8_t)i;
516  if (d == 0xFE) {
517  d = 0xF0;
518  }
519  tx_data[i] = d;
520  }
521  if (zero_window_probe_from_unsent) {
523  } else {
524  tx_data[0] = expected;
525  }
526 
527  /* initialize local vars */
528  IP4_ADDR(&local_ip, 192, 168, 1, 1);
529  IP4_ADDR(&remote_ip, 192, 168, 1, 2);
530  IP4_ADDR(&netmask, 255, 255, 255, 0);
531  test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask);
532  memset(&counters, 0, sizeof(counters));
533  memset(&txcounters, 0, sizeof(txcounters));
534 
535  /* create and initialize the pcb */
537  EXPECT_RET(pcb != NULL);
538  tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
539  pcb->mss = TCP_MSS;
540  /* disable initial congestion window (we don't send a SYN here...) */
541  pcb->cwnd = pcb->snd_wnd;
542 
543  /* send a full window (minus 1 packets) of TCP data in MSS-sized chunks */
544  sent_total = 0;
545  if ((TCP_WND - TCP_MSS) % TCP_MSS != 0) {
546  u16_t initial_data_len = (TCP_WND - TCP_MSS) % TCP_MSS;
547  err = tcp_write(pcb, &tx_data[sent_total], initial_data_len, TCP_WRITE_FLAG_COPY);
548  EXPECT_RET(err == ERR_OK);
549  err = tcp_output(pcb);
550  EXPECT_RET(err == ERR_OK);
551  EXPECT(txcounters.num_tx_calls == 1);
552  EXPECT(txcounters.num_tx_bytes == initial_data_len + 40U);
553  memset(&txcounters, 0, sizeof(txcounters));
554  sent_total += initial_data_len;
555  }
556  for (; sent_total < (TCP_WND - TCP_MSS); sent_total += TCP_MSS) {
557  err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
558  EXPECT_RET(err == ERR_OK);
559  err = tcp_output(pcb);
560  EXPECT_RET(err == ERR_OK);
561  EXPECT(txcounters.num_tx_calls == 1);
562  EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U);
563  memset(&txcounters, 0, sizeof(txcounters));
564  }
565  EXPECT(sent_total == (TCP_WND - TCP_MSS));
566 
567  /* now ACK the packet before the first */
568  p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
570  /* ensure this didn't trigger a retransmission */
571  EXPECT(txcounters.num_tx_calls == 0);
572  EXPECT(txcounters.num_tx_bytes == 0);
573 
574  EXPECT(pcb->persist_backoff == 0);
575  /* send the last packet, now a complete window has been sent */
576  err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
577  sent_total += TCP_MSS;
578  EXPECT_RET(err == ERR_OK);
579  err = tcp_output(pcb);
580  EXPECT_RET(err == ERR_OK);
581  EXPECT(txcounters.num_tx_calls == 1);
582  EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U);
583  memset(&txcounters, 0, sizeof(txcounters));
584  EXPECT(pcb->persist_backoff == 0);
585 
586  if (zero_window_probe_from_unsent) {
587  /* ACK all data but close the TX window */
588  p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, TCP_WND, TCP_ACK, 0);
590  /* ensure this didn't trigger any transmission */
591  EXPECT(txcounters.num_tx_calls == 0);
592  EXPECT(txcounters.num_tx_bytes == 0);
593  EXPECT(pcb->persist_backoff == 1);
594  }
595 
596  /* send one byte more (out of window) -> persist timer starts */
597  err = tcp_write(pcb, &tx_data[sent_total], 1, TCP_WRITE_FLAG_COPY);
598  EXPECT_RET(err == ERR_OK);
599  err = tcp_output(pcb);
600  EXPECT_RET(err == ERR_OK);
601  EXPECT(txcounters.num_tx_calls == 0);
602  EXPECT(txcounters.num_tx_bytes == 0);
603  memset(&txcounters, 0, sizeof(txcounters));
604  if (!zero_window_probe_from_unsent) {
605  /* no persist timer unless a zero window announcement has been received */
606  EXPECT(pcb->persist_backoff == 0);
607  } else {
608  EXPECT(pcb->persist_backoff == 1);
609 
610  /* call tcp_timer some more times to let persist timer count up */
611  for (i = 0; i < 4; i++) {
612  test_tcp_tmr();
613  EXPECT(txcounters.num_tx_calls == 0);
614  EXPECT(txcounters.num_tx_bytes == 0);
615  }
616 
617  /* this should trigger the zero-window-probe */
618  txcounters.copy_tx_packets = 1;
619  test_tcp_tmr();
620  txcounters.copy_tx_packets = 0;
621  EXPECT(txcounters.num_tx_calls == 1);
622  EXPECT(txcounters.num_tx_bytes == 1 + 40U);
623  EXPECT(txcounters.tx_packets != NULL);
624  if (txcounters.tx_packets != NULL) {
625  u8_t sent;
626  u16_t ret;
627  ret = pbuf_copy_partial(txcounters.tx_packets, &sent, 1, 40U);
628  EXPECT(ret == 1);
629  EXPECT(sent == expected);
630  }
631  if (txcounters.tx_packets != NULL) {
632  pbuf_free(txcounters.tx_packets);
633  txcounters.tx_packets = NULL;
634  }
635  }
636 
637  /* make sure the pcb is freed */
638  EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
639  tcp_abort(pcb);
640  EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
641 }
struct tcp_pcb * test_tcp_new_counters_pcb(struct test_tcp_counters *counters)
Definition: tcp_helper.c:223
void test_tcp_init_netif(struct netif *netif, struct test_tcp_txcounters *txcounters, ip_addr_t *ip_addr, ip_addr_t *netmask)
Definition: tcp_helper.c:283
#define U(x)
Definition: wordpad.c:44
GLint GLint GLsizei GLuint * counters
Definition: glext.h:11114
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
Definition: ip_addr.h:64
static __inline void tcp_set_state(struct sock *sk, int state)
Definition: tcpcore.h:3280
#define IP4_ADDR(ipaddr, a, b, c, d)
Definition: ip_addr.h:139
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define EXPECT_RET(x)
Definition: lwip_check.h:12
#define TCP_WND
Definition: opt.h:923
smooth NULL
Definition: ftsmooth.c:416
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:618
s8_t err_t
Definition: err.h:47
static END_TEST u8_t tx_data[TCP_WND *2]
Definition: test_tcp.c:297
#define ERR_OK
Definition: err.h:52
#define d
Definition: ke_i.h:81
Definition: pbuf.h:79
void test_tcp_input(struct pbuf *p, struct netif *inp)
Definition: tcp_helper.c:238
struct pbuf * tcp_create_rx_segment(struct tcp_pcb *pcb, void *data, size_t data_len, u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags)
Definition: tcp_helper.c:118
Definition: netif.h:136
int ret
Definition: msg.h:34
#define err(...)
u16_t pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
Definition: pbuf.c:918
unsigned char u8_t
Definition: cc.h:23
#define TCP_MSS
Definition: opt.h:956
struct pbuf * tcp_create_rx_segment_wnd(struct tcp_pcb *pcb, void *data, size_t data_len, u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags, u16_t wnd)
Definition: tcp_helper.c:130
unsigned short u16_t
Definition: cc.h:24
#define EXPECT(a, b, c, d, e, f)
Definition: vartest.c:1303
static void test_tcp_tmr(void)
Definition: test_tcp.c:22
GLfloat GLfloat p
Definition: glext.h:8902
#define memset(x, y, z)
Definition: compat.h:39
BOOL expected
Definition: store.c:2063

Referenced by START_TEST().

Variable Documentation

◆ test_tcp_timer

u8_t test_tcp_timer
static

Definition at line 18 of file test_tcp.c.

Referenced by tcp_setup(), and test_tcp_tmr().

◆ tx_data

END_TEST u8_t tx_data[TCP_WND *2]
static

Definition at line 297 of file test_tcp.c.

Referenced by START_TEST(), and test_tcp_tx_full_window_lost().