10#pragma warning(disable: 4307)
13#if !LWIP_STATS || !TCP_STATS || !MEMP_STATS
14#error "This tests needs TCP- and MEMP-statistics enabled"
16#if TCP_SND_BUF <= TCP_WND
17#error "This tests needs TCP_SND_BUF to be > TCP_WND"
21#define SEQNO1 (0xFFFFFF00 - TCP_MSS)
50 struct tcp_pcb dummy_pcb;
58 tcp_ticks = 0 - (tcp_next_iss(&dummy_pcb) - 6510);
59 tcp_next_iss(&dummy_pcb);
91 fail_unless(pcb !=
NULL);
103 struct tcp_pcb *pcb, *pcbl;
104 struct tcp_pcb_listen *lpcb;
121 err = tcp_bind(pcb, &
netif.ip_addr, 1234);
123 pcbl = tcp_listen(pcb);
126 lpcb = (
struct tcp_pcb_listen *)pcbl;
128 ip_addr_set_ip4_u32_val(src_addr,
lwip_htonl(
lwip_ntohl(ip_addr_get_ip4_u32(&lpcb->local_ip)) + 1));
165 char data[] = {1, 2, 3, 4};
173 data_len =
sizeof(
data);
176 counters.expected_data_len = data_len;
215 const u32_t new_data_len = 40;
220 data_len =
sizeof(
data);
224 counters.expected_data_len = data_len;
237 if (
p->next !=
NULL) {
272 fail_unless(err2 ==
ERR_OK);
287 if ((
p->len == 1) && (
p->tot_len == 1)) {
343 memset(&txcounters, 0,
sizeof(txcounters));
387 char data[] = {1, 2, 3, 4};
388 u16_t data_len, chksum;
396 data_len =
sizeof(
data);
399 counters.expected_data_len = data_len;
420 hdr->chksum = chksum;
453 char data1[] = { 1, 2, 3, 4};
454 char data2[] = { 5, 6, 7, 8};
455 char data3[] = { 9, 10, 11, 12};
456 char data4[] = {13, 14, 15, 16};
457 char data5[] = {17, 18, 19, 20};
472 pcb->cwnd = pcb->snd_wnd;
475 err = tcp_write(pcb,
data1,
sizeof(
data1), TCP_WRITE_FLAG_COPY);
477 err = tcp_output(pcb);
481 memset(&txcounters, 0,
sizeof(txcounters));
489 err = tcp_write(pcb,
data2,
sizeof(
data2), TCP_WRITE_FLAG_COPY);
491 err = tcp_output(pcb);
495 memset(&txcounters, 0,
sizeof(txcounters));
503 err = tcp_write(pcb,
data3,
sizeof(
data3), TCP_WRITE_FLAG_COPY);
505 err = tcp_output(pcb);
510 memset(&txcounters, 0,
sizeof(txcounters));
518 err = tcp_write(pcb,
data4,
sizeof(
data4), TCP_WRITE_FLAG_COPY);
526 memset(&txcounters, 0,
sizeof(txcounters));
530 err = tcp_write(pcb,
data5,
sizeof(
data5), TCP_WRITE_FLAG_COPY);
536 memset(&txcounters, 0,
sizeof(txcounters));
546 err = tcp_output(pcb);
550 memset(&txcounters, 0,
sizeof(txcounters));
553 err = tcp_write(pcb,
data5,
sizeof(
data5), TCP_WRITE_FLAG_COPY);
555 err = tcp_output(pcb);
558 err = tcp_write(pcb,
data5,
sizeof(
data5), TCP_WRITE_FLAG_COPY);
560 err = tcp_output(pcb);
563 err = tcp_write(pcb,
data5,
sizeof(
data5), TCP_WRITE_FLAG_COPY);
565 err = tcp_output(pcb);
568 err = tcp_write(pcb,
data5,
sizeof(
data5), TCP_WRITE_FLAG_COPY);
570 err = tcp_output(pcb);
580 err = tcp_write(pcb,
data5,
sizeof(
data5), TCP_WRITE_FLAG_COPY);
582 err = tcp_output(pcb);
585 err = tcp_write(pcb,
data5,
sizeof(
data5), TCP_WRITE_FLAG_COPY);
587 err = tcp_output(pcb);
616 struct tcp_seg *
s = segs;
618 for (
i = 0;
i < num_expected;
i++,
s =
s->next) {
637 u16_t sent_total = 0;
657 pcb->ssthresh = pcb->cwnd;
660 for (
i = 0;
i < 6;
i++) {
667 err = tcp_output(pcb);
671 memset(&txcounters, 0,
sizeof(txcounters));
684 memset(&txcounters, 0,
sizeof(txcounters));
689 EXPECT(pcb->dupacks == 0);
693 EXPECT(pcb->dupacks == 1);
697 EXPECT(pcb->dupacks == 2);
701 EXPECT(pcb->dupacks == 3);
703 memset(&txcounters, 0,
sizeof(txcounters));
723 struct tcp_pcb dummy_pcb_for_iss;
726 u16_t sent_total = 0;
739 tcp_ticks = 0 - tcp_next_iss(&dummy_pcb_for_iss);
740 tcp_ticks =
SEQNO1 - tcp_next_iss(&dummy_pcb_for_iss);
749 for (
i = 0;
i < 6;
i++) {
756 err = tcp_output(pcb);
760 memset(&txcounters, 0,
sizeof(txcounters));
766 for (
i = 0;
i < 10;
i++) {
777 pcb->cwnd = pcb->snd_wnd;
779 err = tcp_output(pcb);
813 if (zero_window_probe_from_unsent) {
829 pcb->cwnd = pcb->snd_wnd;
835 err = tcp_write(pcb, &
tx_data[sent_total], initial_data_len, TCP_WRITE_FLAG_COPY);
837 err = tcp_output(pcb);
841 memset(&txcounters, 0,
sizeof(txcounters));
842 sent_total += initial_data_len;
847 err = tcp_output(pcb);
851 memset(&txcounters, 0,
sizeof(txcounters));
862 EXPECT(pcb->persist_backoff == 0);
867 err = tcp_output(pcb);
871 memset(&txcounters, 0,
sizeof(txcounters));
872 EXPECT(pcb->persist_backoff == 0);
874 if (zero_window_probe_from_unsent) {
882 EXPECT(pcb->snd_wnd == 0);
883 EXPECT(pcb->persist_backoff == 0);
887 err = tcp_write(pcb, &
tx_data[sent_total], 1, TCP_WRITE_FLAG_COPY);
889 err = tcp_output(pcb);
893 memset(&txcounters, 0,
sizeof(txcounters));
894 if (!zero_window_probe_from_unsent) {
896 EXPECT(pcb->persist_backoff == 0);
898 EXPECT(pcb->persist_backoff == 1);
901 for (
i = 0;
i < 4;
i++) {
956 char data1a[] = { 1, 2, 3};
957 char data1b[] = { 4};
958 char data2a[] = { 5, 6, 7, 8};
959 char data2b[] = { 5, 6, 7};
960 char data3[] = { 9, 10, 11, 12, 12};
961 char data4[] = { 13, 14, 15, 16,17};
976 pcb->cwnd = pcb->snd_wnd;
979 err = tcp_write(pcb, data1a,
sizeof(data1a), TCP_WRITE_FLAG_COPY);
981 err = tcp_write(pcb, data1b,
sizeof(data1b), TCP_WRITE_FLAG_COPY);
983 err = tcp_output(pcb);
987 memset(&txcounters, 0,
sizeof(txcounters));
995 err = tcp_write(pcb, data2a,
sizeof(data2a), TCP_WRITE_FLAG_COPY);
997 err = tcp_write(pcb, data2b,
sizeof(data2b), TCP_WRITE_FLAG_COPY);
999 err = tcp_output(pcb);
1003 memset(&txcounters, 0,
sizeof(txcounters));
1005 err = tcp_write(pcb,
data3,
sizeof(
data3), TCP_WRITE_FLAG_COPY);
1007 err = tcp_output(pcb);
1011 memset(&txcounters, 0,
sizeof(txcounters));
1018 tcp_nagle_disable(pcb);
1021 for (
i = 0;
i < 20;
i++) {
1032 memset(&txcounters, 0,
sizeof(txcounters));
1034 tcp_nagle_enable(pcb);
1037 for (
i = 0;
i < 20;
i++) {
1048 memset(&txcounters, 0,
sizeof(txcounters));
1051 err = tcp_write(pcb,
data4,
sizeof(
data4), TCP_WRITE_FLAG_COPY);
1054 tcp_nagle_disable(pcb);
1055 err = tcp_output(pcb);
1060 memset(&txcounters, 0,
sizeof(txcounters));
1073 struct tcp_pcb* pcb;
1077 u16_t sent_total = 0;
1098 for (
i = 0;
i < 5;
i++) {
1105 err = tcp_output(pcb);
1109 memset(&txcounters, 0,
sizeof(txcounters));
1115 while (!(pcb->flags & TF_RTO)) {
1124 memset(&txcounters, 0,
sizeof(txcounters));
1127 EXPECT(pcb->rto_end == pcb->snd_nxt);
1129 EXPECT(pcb->cwnd == pcb->mss);
1139 EXPECT(pcb->rto_end == pcb->snd_nxt);
1147 memset(&txcounters, 0,
sizeof(txcounters));
1151 EXPECT(pcb->flags & TF_RTO);
1153 EXPECT(pcb->cwnd == (tcpwnd_size_t)(2 * pcb->mss));
1155 EXPECT(pcb->rto_end == pcb->snd_nxt);
1163 memset(&txcounters, 0,
sizeof(txcounters));
1167 EXPECT(pcb->flags & TF_RTO);
1169 EXPECT(pcb->cwnd == (tcpwnd_size_t)(3 * pcb->mss));
1171 EXPECT(TCP_SEQ_GT(pcb->snd_nxt, pcb->rto_end));
1176 EXPECT(!(pcb->flags & TF_RTO));
1179 EXPECT(pcb->cwnd == (tcpwnd_size_t)(3 * pcb->mss));
1180 EXPECT(pcb->cwnd >= pcb->ssthresh);
1182 EXPECT(pcb->bytes_acked == (tcpwnd_size_t)(2 * pcb->mss));
1196 struct tcp_pcb *pcb, *
cur;
1199 const size_t max_wait_ctr = 1024 * 1024;
1221 err = tcp_output(pcb);
1225 memset(&txcounters, 0,
sizeof(txcounters));
1232 for (
i = 0; !(pcb->flags & TF_RTO) &&
i < max_wait_ctr;
i++) {
1294 struct tcp_pcb *pcb, *
cur;
1297 const size_t max_wait_ctr = 1024 * 1024;
1298 const u16_t tcp_syn_opts_len = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_MSS|TF_SEG_OPTS_WND_SCALE|TF_SEG_OPTS_SACK_PERM|TF_SEG_OPTS_TS);
1327 for (
i = 0; !(pcb->flags & TF_RTO) &&
i < max_wait_ctr;
i++) {
1390 struct tcp_pcb *pcb, *
cur;
1415 err = tcp_output(pcb);
1423 memset(&txcounters, 0,
sizeof(txcounters));
1431 EXPECT(pcb->persist_backoff == 0);
1432 EXPECT(pcb->snd_wnd == 0);
1437 err = tcp_output(pcb);
1445 EXPECT(pcb->persist_backoff == 1);
1452 EXPECT(pcb->persist_probe == 0);
1453 while (pcb->persist_probe == 0) {
1458 memset(&txcounters, 0,
sizeof(txcounters));
1464 EXPECT(pcb->persist_backoff > 1);
1465 EXPECT(pcb->persist_probe == 0);
1466 EXPECT(pcb->snd_wnd == 0);
1519 struct tcp_pcb *pcb;
1543 pcb->snd_wnd_max = 3 *
TCP_MSS;
1549 err = tcp_output(pcb);
1557 memset(&txcounters, 0,
sizeof(txcounters));
1564#if TCP_OVERSIZE_DBGCHECK
1565 EXPECT(pcb->unsent->oversize_left == pcb->unsent_oversize);
1580 EXPECT(pcb->persist_backoff == 1);
1587 for (
i = 0;
i < 4;
i++) {
1599 EXPECT(pcb->persist_backoff == 0);
1610 EXPECT(pcb->unsent_oversize == 0);
1611#if TCP_OVERSIZE_DBGCHECK
1613 EXPECT(pcb->unacked->oversize_left == 0);
1615 EXPECT(pcb->unsent->oversize_left == pcb->unsent_oversize);
1632 memset(&txcounters, 0,
sizeof(txcounters));
1678 TESTFUNC(test_tcp_listen_passive_open),
1680 TESTFUNC(test_tcp_recv_inseq_trim),
1683 TESTFUNC(test_tcp_malformed_header),
1684 TESTFUNC(test_tcp_fast_retx_recover),
1685 TESTFUNC(test_tcp_fast_rexmit_wraparound),
1686 TESTFUNC(test_tcp_rto_rexmit_wraparound),
1687 TESTFUNC(test_tcp_tx_full_window_lost_from_unacked),
1688 TESTFUNC(test_tcp_tx_full_window_lost_from_unsent),
1689 TESTFUNC(test_tcp_retx_add_to_sent),
1692 TESTFUNC(test_tcp_rto_timeout_link_down),
1693 TESTFUNC(test_tcp_rto_timeout_syn_sent),
1694 TESTFUNC(test_tcp_rto_timeout_syn_sent_link_down),
1696 TESTFUNC(test_tcp_zwp_timeout_link_down),
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
STREAM tcp_recv(STREAM s, uint32 length)
RD_BOOL tcp_connect(char *server)
static const char data4[]
static const WCHAR data3[]
static const WCHAR data5[]
static const WCHAR data6[]
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLint GLint GLsizei GLuint * counters
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
#define LWIP_UNUSED_ARG(x)
#define PBUF_POOL_BUFSIZE
void netif_set_link_down(struct netif *netif)
u8_t pbuf_free(struct pbuf *p)
u16_t pbuf_copy_partial(const struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
u16_t ip_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, const ip_addr_t *src, const ip_addr_t *dest)
#define TCPH_HDRLEN_FLAGS_SET(phdr, len, flags)
Suite * create_suite(const char *name, testfunc *tests, size_t num_tests, SFun setup, SFun teardown)
#define EXPECT_RETX(x, y)
void lwip_check_ensure_no_alloc(unsigned int skip)
static struct test_info tests[]
struct netif * netif_list
struct netif * netif_default
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
#define MEMP_STATS_GET(x, i)
void test_tcp_init_netif(struct netif *netif, struct test_tcp_txcounters *txcounters, const ip_addr_t *ip_addr, const ip_addr_t *netmask)
void test_tcp_input(struct pbuf *p, struct netif *inp)
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)
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)
struct tcp_pcb * test_tcp_new_counters_pcb(struct test_tcp_counters *counters)
void tcp_remove_all(void)
const ip_addr_t test_local_ip
const ip_addr_t test_remote_ip
struct pbuf * tcp_create_segment(ip_addr_t *src_ip, ip_addr_t *dst_ip, u16_t src_port, u16_t dst_port, void *data, size_t data_len, u32_t seqno, u32_t ackno, u8_t headerflags)
void tcp_close(struct sock *sk, long timeout)
static __inline void tcp_set_state(struct sock *sk, int state)
static ip4_addr_t test_netmask
static END_TEST u8_t tx_data[TCP_WND *2]
static void check_seqnos(struct tcp_seg *segs, int num_expected, u32_t *seqnos_expected)
static void tcp_teardown(void)
static END_TEST err_t test_tcp_recv_expect1byte(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
END_TEST Suite * tcp_suite(void)
static struct netif * old_netif_list
static END_TEST void test_tcp_rto_timeout_impl(int link_down)
static struct netif * old_netif_default
static void test_tcp_tmr(void)
static END_TEST void test_tcp_zwp_timeout_impl(int link_down)
static u8_t test_tcp_timer
static void tcp_setup(void)
static err_t test_tcp_recv_expectclose(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
static END_TEST void test_tcp_rto_timeout_syn_sent_impl(int link_down)
static END_TEST void test_tcp_tx_full_window_lost(u8_t zero_window_probe_from_unsent)