From 2506e5967c50b4dcd6afa6f3968cd1178eca814f Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 5 Nov 2011 18:54:49 +0000 Subject: [PATCH] [LWIP] - Properly sync to lwIP 1.4.0 - No code changes (except unit tests) svn path=/trunk/; revision=54302 --- reactos/lib/drivers/lwip/CHANGELOG | 156 +++++++++++++++- reactos/lib/drivers/lwip/UPGRADING | 7 +- reactos/lib/drivers/lwip/doc/rawapi.txt | 5 +- reactos/lib/drivers/lwip/doc/sys_arch.txt | 12 -- reactos/lib/drivers/lwip/src/core/tcp_in.c | 14 -- .../lib/drivers/lwip/test/unit/lwip_check.h | 2 +- .../drivers/lwip/test/unit/lwip_unittests.c | 4 + .../drivers/lwip/test/unit/tcp/tcp_helper.c | 33 +++- .../drivers/lwip/test/unit/tcp/tcp_helper.h | 8 +- .../lib/drivers/lwip/test/unit/tcp/test_tcp.c | 6 +- .../drivers/lwip/test/unit/tcp/test_tcp_oos.c | 167 ++++++++++++++---- .../lib/drivers/lwip/test/unit/udp/test_udp.c | 12 -- 12 files changed, 333 insertions(+), 93 deletions(-) diff --git a/reactos/lib/drivers/lwip/CHANGELOG b/reactos/lib/drivers/lwip/CHANGELOG index d0e15f2a3ea..6e27a66b8f0 100644 --- a/reactos/lib/drivers/lwip/CHANGELOG +++ b/reactos/lib/drivers/lwip/CHANGELOG @@ -1,18 +1,29 @@ -FUTURE - - * TODO: The lwIP source code makes some invalid assumptions on processor - word-length, storage sizes and alignment. See the mailing lists for - problems with exoteric (/DSP) architectures showing these problems. - We still have to fix some of these issues neatly. - HISTORY (CVS HEAD) * [Enter new changes just after this line - do not remove this line] + ++ New features: + + + ++ Bugfixes: + + + + +(STABLE-1.4.0) + ++ New features: + 2011-03-27: Simon Goldschmidt + * tcp_impl.h, tcp_in.c, tcp_out.c: Removed 'dataptr' from 'struct tcp_seg' and + calculate it in tcp_zero_window_probe (the only place where it was used). + + 2010-11-21: Simon Goldschmidt + * dhcp.c/.h: Added a function to deallocate the struct dhcp from a netif + (fixes bug #31525). + 2010-07-12: Simon Goldschmidt (patch by Stephane Lesage) * ip.c, udp.c/.h, pbuf.h, sockets.c: task #10495: Added support for IP_MULTICAST_LOOP at socket- and raw-API level. @@ -229,6 +240,137 @@ HISTORY ++ Bugfixes: + 2011-04-20: Simon Goldschmidt + * sys_arch.txt: sys_arch_timeouts() is not needed any more. + + 2011-04-13: Simon Goldschmidt + * tcp.c, udp.c: Fixed bug #33048 (Bad range for IP source port numbers) by + using ports in the IANA private/dynamic range (49152 through 65535). + + 2011-03-29: Simon Goldschmidt, patch by Emil Lhungdahl: + * etharp.h/.c: Fixed broken VLAN support. + + 2011-03-27: Simon Goldschmidt + * tcp.c: Fixed bug #32926 (TCP_RMV(&tcp_bound_pcbs) is called on unbound tcp + pcbs) by checking if the pcb was bound (local_port != 0). + + 2011-03-27: Simon Goldschmidt + * ppp.c: Fixed bug #32280 (ppp: a pbuf is freed twice) + + 2011-03-27: Simon Goldschmidt + * sockets.c: Fixed bug #32906: lwip_connect+lwip_send did not work for udp and + raw pcbs with LWIP_TCPIP_CORE_LOCKING==1. + + 2011-03-27: Simon Goldschmidt + * tcp_out.c: Fixed bug #32820 (Outgoing TCP connections created before route + is present never times out) by starting retransmission timer before checking + route. + + 2011-03-22: Simon Goldschmidt + * ppp.c: Fixed bug #32648 (PPP code crashes when terminating a link) by only + calling sio_read_abort() if the file descriptor is valid. + + 2011-03-14: Simon Goldschmidt + * err.h/.c, sockets.c, api_msg.c: fixed bug #31748 (Calling non-blocking connect + more than once can render a socket useless) since it mainly involves changing + "FATAL" classification of error codes: ERR_USE and ERR_ISCONN just aren't fatal. + + 2011-03-13: Simon Goldschmidt + * sockets.c: fixed bug #32769 (ESHUTDOWN is linux-specific) by fixing + err_to_errno_table (ERR_CLSD: ENOTCONN instead of ESHUTDOWN), ERR_ISCONN: + use EALRADY instead of -1 + + 2011-03-13: Simon Goldschmidt + * api_lib.c: netconn_accept: return ERR_ABRT instead of ERR_CLSD if the + connection has been aborted by err_tcp (since this is not a normal closing + procedure). + + 2011-03-13: Simon Goldschmidt + * tcp.c: tcp_bind: return ERR_VAL instead of ERR_ISCONN when trying to bind + with pcb->state != CLOSED + + 2011-02-17: Simon Goldschmidt + * rawapi.txt: Fixed bug #32561 tcp_poll argument definition out-of-order in + documentation + + 2011-02-17: Simon Goldschmidt + * many files: Added missing U/UL modifiers to fix 16-bit-arch portability. + + 2011-01-24: Simon Goldschmidt + * sockets.c: Fixed bug #31741: lwip_select seems to have threading problems + + 2010-12-02: Simon Goldschmidt + * err.h: Fixed ERR_IS_FATAL so that ERR_WOULDBLOCK is not fatal. + + 2010-11-23: Simon Goldschmidt + * api.h, api_lib.c, api_msg.c, sockets.c: netconn.recv_avail is only used for + LWIP_SO_RCVBUF and ioctl/FIONREAD. + + 2010-11-23: Simon Goldschmidt + * etharp.c: Fixed bug #31720: ARP-queueing: RFC 1122 recommends to queue at + least 1 packet -> ARP_QUEUEING==0 now queues the most recent packet. + + 2010-11-23: Simon Goldschmidt + * tcp_in.c: Fixed bug #30577: tcp_input: don't discard ACK-only packets after + refusing 'refused_data' again. + + 2010-11-22: Simon Goldschmidt + * sockets.c: Fixed bug #31590: getsockopt(... SO_ERROR ...) gives EINPROGRESS + after a successful nonblocking connection. + + 2010-11-22: Simon Goldschmidt + * etharp.c: Fixed bug #31722: IP packets sent with an AutoIP source addr + must be sent link-local + + 2010-11-22: Simon Goldschmidt + * timers.c: patch #7329: tcp_timer_needed prototype was ifdef'ed out for + LWIP_TIMERS==0 + + 2010-11-20: Simon Goldschmidt + * sockets.c: Fixed bug #31170: lwip_setsockopt() does not set socket number + + 2010-11-20: Simon Goldschmidt + * sockets.h: Fixed bug #31304: Changed SHUT_RD, SHUT_WR and SHUT_RDWR to + resemble other stacks. + + 2010-11-20: Simon Goldschmidt + * dns.c: Fixed bug #31535: TCP_SND_QUEUELEN must be at least 2 or else + no-copy TCP writes will never succeed. + + 2010-11-20: Simon Goldschmidt + * dns.c: Fixed bug #31701: Error return value from dns_gethostbyname() does + not match documentation: return ERR_ARG instead of ERR_VAL if not + initialized or wrong argument. + + 2010-10-20: Simon Goldschmidt + * sockets.h: Fixed bug #31385: sizeof(struct sockaddr) is 30 but should be 16 + + 2010-10-05: Simon Goldschmidt + * dhcp.c: Once again fixed #30038: DHCP/AutoIP cooperation failed when + replugging the network cable after an AutoIP address was assigned. + + 2010-08-10: Simon Goldschmidt + * tcp.c: Fixed bug #30728: tcp_new_port() did not check listen pcbs + + 2010-08-03: Simon Goldschmidt + * udp.c, raw.c: Don't chain empty pbufs when sending them (fixes bug #30625) + + 2010-08-01: Simon Goldschmidt (patch by Greg Renda) + * ppp.c: Applied patch #7264 (PPP protocols are rejected incorrectly on big + endian architectures) + + 2010-07-28: Simon Goldschmidt + * api_lib.c, api_msg.c, sockets.c, mib2.c: Fixed compilation with TCP or UDP + disabled. + + 2010-07-27: Simon Goldschmidt + * tcp.c: Fixed bug #30565 (tcp_connect() check bound list): that check did no + harm but never did anything + + 2010-07-21: Simon Goldschmidt + * ip.c: Fixed invalid fix for bug #30402 (CHECKSUM_GEN_IP_INLINE does not + add IP options) + 2010-07-16: Kieran Mansley * msg_in.c: Fixed SNMP ASN constant defines to not use ! operator diff --git a/reactos/lib/drivers/lwip/UPGRADING b/reactos/lib/drivers/lwip/UPGRADING index 215ad88d1e3..6501107a7e8 100644 --- a/reactos/lib/drivers/lwip/UPGRADING +++ b/reactos/lib/drivers/lwip/UPGRADING @@ -111,11 +111,16 @@ with newer versions. * Added const char* name to mem- and memp-stats for easier debugging. * Calculate the TCP/UDP checksum while copying to only fetch data once: - Define LWIP_CHKSUM_COPY to a memcpy-like function that returns the checksum + Define LWIP_CHKSUM_COPY to a memcpy-like function that returns the checksum * Added SO_REUSE_RXTOALL to pass received UDP broadcast/multicast packets to more than one pcb. + * Changed the semantics of ARP_QUEUEING==0: ARP_QUEUEING now cannot be turned + off any more, if this is set to 0, only one packet (the most recent one) is + queued (like demanded by RFC 1122). + + ++ Major bugfixes/improvements * Implemented tcp_shutdown() to only shut down one end of a connection diff --git a/reactos/lib/drivers/lwip/doc/rawapi.txt b/reactos/lib/drivers/lwip/doc/rawapi.txt index 65f82bc5d19..bd452cf9344 100644 --- a/reactos/lib/drivers/lwip/doc/rawapi.txt +++ b/reactos/lib/drivers/lwip/doc/rawapi.txt @@ -251,8 +251,9 @@ if a call to tcp_write() has failed because memory wasn't available, the application may use the polling functionality to call tcp_write() again when the connection has been idle for a while. -- void tcp_poll(struct tcp_pcb *pcb, u8_t interval, - err_t (* poll)(void *arg, struct tcp_pcb *tpcb)) +- void tcp_poll(struct tcp_pcb *pcb, + err_t (* poll)(void *arg, struct tcp_pcb *tpcb), + u8_t interval) Specifies the polling interval and the callback function that should be called to poll the application. The interval is specified in diff --git a/reactos/lib/drivers/lwip/doc/sys_arch.txt b/reactos/lib/drivers/lwip/doc/sys_arch.txt index 66310a91e48..38377b66551 100644 --- a/reactos/lib/drivers/lwip/doc/sys_arch.txt +++ b/reactos/lib/drivers/lwip/doc/sys_arch.txt @@ -123,18 +123,6 @@ The following functions must be implemented by the sys_arch: sys_arch_mbox_fetch(mbox,msg,1) although this would introduce unnecessary delays. -- struct sys_timeouts *sys_arch_timeouts(void) - - Returns a pointer to the per-thread sys_timeouts structure. In lwIP, - each thread has a list of timeouts which is repressented as a linked - list of sys_timeout structures. The sys_timeouts structure holds a - pointer to a linked list of timeouts. This function is called by - the lwIP timeout scheduler and must not return a NULL value. - - In a single thread sys_arch implementation, this function will - simply return a pointer to a global sys_timeouts variable stored in - the sys_arch module. - If threads are supported by the underlying operating system and if such functionality is needed in lwIP, the following function will have to be implemented as well: diff --git a/reactos/lib/drivers/lwip/src/core/tcp_in.c b/reactos/lib/drivers/lwip/src/core/tcp_in.c index e1bfe8874b0..399d32f508e 100644 --- a/reactos/lib/drivers/lwip/src/core/tcp_in.c +++ b/reactos/lib/drivers/lwip/src/core/tcp_in.c @@ -79,20 +79,6 @@ static void tcp_parseopt(struct tcp_pcb *pcb); static err_t tcp_listen_input(struct tcp_pcb_listen *pcb); static err_t tcp_timewait_input(struct tcp_pcb *pcb); -static const char * const tcp_state_str[] = { - "CLOSED", - "LISTEN", - "SYN_SENT", - "SYN_RCVD", - "ESTABLISHED", - "FIN_WAIT_1", - "FIN_WAIT_2", - "CLOSE_WAIT", - "CLOSING", - "LAST_ACK", - "TIME_WAIT" -}; - /** * The initial input processing of TCP. It verifies the TCP header, demultiplexes * the segment between the PCBs and passes it on to tcp_process(), which implements diff --git a/reactos/lib/drivers/lwip/test/unit/lwip_check.h b/reactos/lib/drivers/lwip/test/unit/lwip_check.h index d8984a127c2..e27f55aee36 100644 --- a/reactos/lib/drivers/lwip/test/unit/lwip_check.h +++ b/reactos/lib/drivers/lwip/test/unit/lwip_check.h @@ -23,7 +23,7 @@ static Suite* create_suite(const char* name, TFun *tests, size_t num_tests, SFun Suite *s = suite_create(name); for(i = 0; i < num_tests; i++) { - // Core test case + /* Core test case */ TCase *tc_core = tcase_create("Core"); if ((setup != NULL) || (teardown != NULL)) { tcase_add_checked_fixture(tc_core, setup, teardown); diff --git a/reactos/lib/drivers/lwip/test/unit/lwip_unittests.c b/reactos/lib/drivers/lwip/test/unit/lwip_unittests.c index 2dbeb6d45a7..e0931464602 100644 --- a/reactos/lib/drivers/lwip/test/unit/lwip_unittests.c +++ b/reactos/lib/drivers/lwip/test/unit/lwip_unittests.c @@ -3,6 +3,8 @@ #include "udp/test_udp.h" #include "tcp/test_tcp.h" #include "tcp/test_tcp_oos.h" +#include "core/test_mem.h" +#include "etharp/test_etharp.h" #include "lwip/init.h" @@ -16,6 +18,8 @@ int main() udp_suite, tcp_suite, tcp_oos_suite, + mem_suite, + etharp_suite, }; size_t num = sizeof(suites)/sizeof(void*); LWIP_ASSERT("No suites defined", num > 0); diff --git a/reactos/lib/drivers/lwip/test/unit/tcp/tcp_helper.c b/reactos/lib/drivers/lwip/test/unit/tcp/tcp_helper.c index 0957cbe42ee..b28254088f7 100644 --- a/reactos/lib/drivers/lwip/test/unit/tcp/tcp_helper.c +++ b/reactos/lib/drivers/lwip/test/unit/tcp/tcp_helper.c @@ -1,6 +1,6 @@ #include "tcp_helper.h" -#include "lwip/tcp.h" +#include "lwip/tcp_impl.h" #include "lwip/stats.h" #include "lwip/pbuf.h" #include "lwip/inet_chksum.h" @@ -27,7 +27,6 @@ tcp_remove(struct tcp_pcb* pcb_list) void tcp_remove_all(void) { - //tcp_remove(tcp_bound_pcbs); tcp_remove(tcp_listen_pcbs.pcbs); tcp_remove(tcp_active_pcbs); tcp_remove(tcp_tw_pcbs); @@ -51,14 +50,14 @@ tcp_create_rx_segment(struct tcp_pcb* pcb, void* data, size_t data_len, u32_t se /** Create a TCP segment usable for passing to tcp_input */ struct pbuf* -tcp_create_segment(struct ip_addr* src_ip, struct ip_addr* dst_ip, +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) { struct pbuf* p; struct ip_hdr* iphdr; struct tcp_hdr* tcphdr; - u16_t pbuf_len = sizeof(struct ip_hdr) + sizeof(struct tcp_hdr) + data_len; + u16_t pbuf_len = (u16_t)(sizeof(struct ip_hdr) + sizeof(struct tcp_hdr) + data_len); p = pbuf_alloc(PBUF_RAW, pbuf_len, PBUF_POOL); EXPECT_RETNULL(p != NULL); @@ -83,13 +82,14 @@ tcp_create_segment(struct ip_addr* src_ip, struct ip_addr* dst_ip, tcphdr->ackno = htonl(ackno); TCPH_HDRLEN_SET(tcphdr, sizeof(struct tcp_hdr)/4); TCPH_FLAGS_SET(tcphdr, headerflags); - tcphdr->wnd = htonl(TCP_WND); + tcphdr->wnd = htons(TCP_WND); /* copy data */ memcpy((char*)tcphdr + sizeof(struct tcp_hdr), data, data_len); /* calculate checksum */ - tcphdr->chksum = inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), + + tcphdr->chksum = inet_chksum_pseudo(p, src_ip, dst_ip, IP_PROTO_TCP, p->tot_len); pbuf_header(p, sizeof(struct ip_hdr)); @@ -99,8 +99,8 @@ tcp_create_segment(struct ip_addr* src_ip, struct ip_addr* dst_ip, /** Safely bring a tcp_pcb into the requested state */ void -tcp_set_state(struct tcp_pcb* pcb, enum tcp_state state, struct ip_addr* local_ip, - struct ip_addr* remote_ip, u16_t local_port, u16_t remote_port) +tcp_set_state(struct tcp_pcb* pcb, enum tcp_state state, ip_addr_t* local_ip, + ip_addr_t* remote_ip, u16_t local_port, u16_t remote_port) { /* @todo: are these all states? */ /* @todo: remove from previous list */ @@ -194,3 +194,20 @@ test_tcp_new_counters_pcb(struct test_tcp_counters* counters) } return pcb; } + +/** Calls tcp_input() after adjusting current_iphdr_dest */ +void test_tcp_input(struct pbuf *p, struct netif *inp) +{ + struct ip_hdr *iphdr = (struct ip_hdr*)p->payload; + ip_addr_copy(current_iphdr_dest, iphdr->dest); + ip_addr_copy(current_iphdr_src, iphdr->src); + current_netif = inp; + current_header = iphdr; + + tcp_input(p, inp); + + current_iphdr_dest.addr = 0; + current_iphdr_src.addr = 0; + current_netif = NULL; + current_header = NULL; +} diff --git a/reactos/lib/drivers/lwip/test/unit/tcp/tcp_helper.h b/reactos/lib/drivers/lwip/test/unit/tcp/tcp_helper.h index b61e0f0af3a..af546dc6c28 100644 --- a/reactos/lib/drivers/lwip/test/unit/tcp/tcp_helper.h +++ b/reactos/lib/drivers/lwip/test/unit/tcp/tcp_helper.h @@ -21,16 +21,18 @@ struct test_tcp_counters { /* Helper functions */ void tcp_remove_all(void); -struct pbuf* tcp_create_segment(struct ip_addr* src_ip, struct ip_addr* dst_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); 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); -void tcp_set_state(struct tcp_pcb* pcb, enum tcp_state state, struct ip_addr* local_ip, - struct ip_addr* remote_ip, u16_t local_port, u16_t remote_port); +void tcp_set_state(struct tcp_pcb* pcb, enum tcp_state state, ip_addr_t* local_ip, + ip_addr_t* remote_ip, u16_t local_port, u16_t remote_port); void test_tcp_counters_err(void* arg, err_t err); err_t test_tcp_counters_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err); struct tcp_pcb* test_tcp_new_counters_pcb(struct test_tcp_counters* counters); +void test_tcp_input(struct pbuf *p, struct netif *inp); + #endif diff --git a/reactos/lib/drivers/lwip/test/unit/tcp/test_tcp.c b/reactos/lib/drivers/lwip/test/unit/tcp/test_tcp.c index 350cb0cb93d..0eec3cca725 100644 --- a/reactos/lib/drivers/lwip/test/unit/tcp/test_tcp.c +++ b/reactos/lib/drivers/lwip/test/unit/tcp/test_tcp.c @@ -1,6 +1,6 @@ #include "test_tcp.h" -#include "lwip/tcp.h" +#include "lwip/tcp_impl.h" #include "lwip/stats.h" #include "tcp_helper.h" @@ -50,7 +50,7 @@ START_TEST(test_tcp_recv_inseq) struct tcp_pcb* pcb; struct pbuf* p; char data[] = {1, 2, 3, 4}; - struct ip_addr remote_ip, local_ip; + ip_addr_t remote_ip, local_ip; u16_t data_len; u16_t remote_port = 0x100, local_port = 0x101; struct netif netif; @@ -76,7 +76,7 @@ START_TEST(test_tcp_recv_inseq) EXPECT(p != NULL); if (p != NULL) { /* pass the segment to tcp_input */ - tcp_input(p, &netif); + test_tcp_input(p, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 1); diff --git a/reactos/lib/drivers/lwip/test/unit/tcp/test_tcp_oos.c b/reactos/lib/drivers/lwip/test/unit/tcp/test_tcp_oos.c index 8e4c7f4d0e7..56944e202e2 100644 --- a/reactos/lib/drivers/lwip/test/unit/tcp/test_tcp_oos.c +++ b/reactos/lib/drivers/lwip/test/unit/tcp/test_tcp_oos.c @@ -1,6 +1,6 @@ #include "test_tcp_oos.h" -#include "lwip/tcp.h" +#include "lwip/tcp_impl.h" #include "lwip/stats.h" #include "tcp_helper.h" @@ -60,7 +60,7 @@ tcp_oos_seg_seqno(struct tcp_pcb* pcb, int seg_index) return 0; } -/** Get the tcplen of a segment (by index) on the ooseq list +/** Get the tcplen (datalen + SYN/FIN) of a segment (by index) on the ooseq list * * @param pcb the pcb to check for ooseq segments * @param seg_index index of the segment on the ooseq list @@ -84,6 +84,25 @@ tcp_oos_seg_tcplen(struct tcp_pcb* pcb, int seg_index) return -1; } +/** Get the tcplen (datalen + SYN/FIN) of all segments on the ooseq list + * + * @param pcb the pcb to check for ooseq segments + * @return tcplen of all segment + */ +static int +tcp_oos_tcplen(struct tcp_pcb* pcb) +{ + int len = 0; + struct tcp_seg* seg = pcb->ooseq; + + /* then check the actual segment */ + while(seg != NULL) { + len += TCP_TCPLEN(seg); + seg = seg->next; + } + return len; +} + /* Setup/teardown functions */ static void @@ -115,7 +134,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ) 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - struct ip_addr remote_ip, local_ip; + ip_addr_t remote_ip, local_ip; u16_t data_len; u16_t remote_port = 0x100, local_port = 0x101; struct netif netif; @@ -161,7 +180,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ) EXPECT(p_fin != NULL); if ((pinseq != NULL) && (p_8_9 != NULL) && (p_4_8 != NULL) && (p_4_10 != NULL) && (p_2_14 != NULL) && (p_fin != NULL)) { /* pass the segment to tcp_input */ - tcp_input(p_8_9, &netif); + test_tcp_input(p_8_9, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); @@ -173,7 +192,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ) EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 9); /* includes FIN */ /* pass the segment to tcp_input */ - tcp_input(p_4_8, &netif); + test_tcp_input(p_4_8, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); @@ -187,7 +206,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ) EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */ /* pass the segment to tcp_input */ - tcp_input(p_4_10, &netif); + test_tcp_input(p_4_10, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); @@ -201,35 +220,31 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ) EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */ /* pass the segment to tcp_input */ - tcp_input(p_2_14, &netif); + test_tcp_input(p_2_14, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); EXPECT(counters.recved_bytes == 0); EXPECT(counters.err_calls == 0); /* check ooseq queue */ - EXPECT_OOSEQ(tcp_oos_count(pcb) == 2); + EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 6); - EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */ + EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */ /* pass the segment to tcp_input */ - tcp_input(p_fin, &netif); + test_tcp_input(p_fin, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); EXPECT(counters.recved_bytes == 0); EXPECT(counters.err_calls == 0); /* ooseq queue: unchanged */ - EXPECT_OOSEQ(tcp_oos_count(pcb) == 2); + EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 6); - EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */ + EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */ /* pass the segment to tcp_input */ - tcp_input(pinseq, &netif); + test_tcp_input(pinseq, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 1); EXPECT(counters.recv_calls == 1); @@ -259,7 +274,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - struct ip_addr remote_ip, local_ip; + ip_addr_t remote_ip, local_ip; u16_t data_len; u16_t remote_port = 0x100, local_port = 0x101; struct netif netif; @@ -315,7 +330,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) if ((pinseq != NULL) && (p_1_2 != NULL) && (p_4_8 != NULL) && (p_3_11 != NULL) && (p_2_12 != NULL) && (p_15_1 != NULL) && (p_15_1a != NULL) && (pinseqFIN != NULL)) { /* pass the segment to tcp_input */ - tcp_input(p_1_2, &netif); + test_tcp_input(p_1_2, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); @@ -327,7 +342,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2); /* pass the segment to tcp_input */ - tcp_input(p_4_8, &netif); + test_tcp_input(p_4_8, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); @@ -341,7 +356,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 8); /* pass the segment to tcp_input */ - tcp_input(p_3_11, &netif); + test_tcp_input(p_3_11, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); @@ -356,23 +371,21 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 11); /* pass the segment to tcp_input */ - tcp_input(p_2_12, &netif); + test_tcp_input(p_2_12, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); EXPECT(counters.recved_bytes == 0); EXPECT(counters.err_calls == 0); /* check ooseq queue */ - EXPECT_OOSEQ(tcp_oos_count(pcb) == 3); + EXPECT_OOSEQ(tcp_oos_count(pcb) == 2); EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1); EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1); EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 2); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 1); - EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 2) == 3); - EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 2) == 11); + EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 12); /* pass the segment to tcp_input */ - tcp_input(pinseq, &netif); + test_tcp_input(pinseq, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 1); @@ -381,7 +394,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) EXPECT(pcb->ooseq == NULL); /* pass the segment to tcp_input */ - tcp_input(p_15_1, &netif); + test_tcp_input(p_15_1, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 1); @@ -393,7 +406,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1); /* pass the segment to tcp_input */ - tcp_input(p_15_1a, &netif); + test_tcp_input(p_15_1a, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 1); @@ -405,7 +418,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1); /* pass the segment to tcp_input */ - tcp_input(pinseqFIN, &netif); + test_tcp_input(pinseqFIN, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 1); EXPECT(counters.recv_calls == 2); @@ -421,6 +434,99 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) } END_TEST +static char data_full_wnd[TCP_WND]; + +/** create multiple segments and pass them to tcp_input with the first segment missing + * to simulate overruning the rxwin with ooseq queueing enabled */ +START_TEST(test_tcp_recv_ooseq_overrun_rxwin) +{ + int i, k; + struct test_tcp_counters counters; + struct tcp_pcb* pcb; + struct pbuf *pinseq, *p_ovr; + ip_addr_t remote_ip, local_ip; + u16_t remote_port = 0x100, local_port = 0x101; + struct netif netif; + int datalen = 0; + int datalen2; + LWIP_UNUSED_ARG(_i); + + for(i = 0; i < sizeof(data_full_wnd); i++) { + data_full_wnd[i] = (char)i; + } + + /* initialize local vars */ + memset(&netif, 0, sizeof(netif)); + IP4_ADDR(&local_ip, 192, 168, 1, 1); + IP4_ADDR(&remote_ip, 192, 168, 1, 2); + /* initialize counter struct */ + memset(&counters, 0, sizeof(counters)); + counters.expected_data_len = TCP_WND; + counters.expected_data = data_full_wnd; + + /* create and initialize the pcb */ + pcb = test_tcp_new_counters_pcb(&counters); + EXPECT_RET(pcb != NULL); + tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); + pcb->rcv_nxt = 0x8000; + + /* create segments */ + /* pinseq is sent as last segment! */ + pinseq = tcp_create_rx_segment(pcb, &data_full_wnd[0], TCP_MSS, 0, 0, TCP_ACK); + + for(i = TCP_MSS, k = 0; i < TCP_WND; i += TCP_MSS, k++) { + int count, expected_datalen; + struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], + TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK); + EXPECT(p != NULL); + /* pass the segment to tcp_input */ + test_tcp_input(p, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* check ooseq queue */ + count = tcp_oos_count(pcb); + EXPECT_OOSEQ(count == k+1); + datalen = tcp_oos_tcplen(pcb); + if (i + TCP_MSS < TCP_WND) { + expected_datalen = (k+1)*TCP_MSS; + } else { + expected_datalen = TCP_WND - TCP_MSS; + } + if (datalen != expected_datalen) { + EXPECT_OOSEQ(datalen == expected_datalen); + } + } + + /* pass in one more segment, cleary overrunning the rxwin */ + p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK); + EXPECT(p_ovr != NULL); + /* pass the segment to tcp_input */ + test_tcp_input(p_ovr, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* check ooseq queue */ + EXPECT_OOSEQ(tcp_oos_count(pcb) == k); + datalen2 = tcp_oos_tcplen(pcb); + EXPECT_OOSEQ(datalen == datalen2); + + /* now pass inseq */ + test_tcp_input(pinseq, &netif); + EXPECT(pcb->ooseq == NULL); + + /* make sure the pcb is freed */ + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +} +END_TEST + + /** Create the suite including all tests for this module */ Suite * tcp_oos_suite(void) @@ -428,6 +534,7 @@ tcp_oos_suite(void) TFun tests[] = { test_tcp_recv_ooseq_FIN_OOSEQ, test_tcp_recv_ooseq_FIN_INSEQ, + test_tcp_recv_ooseq_overrun_rxwin, }; return create_suite("TCP_OOS", tests, sizeof(tests)/sizeof(TFun), tcp_oos_setup, tcp_oos_teardown); } diff --git a/reactos/lib/drivers/lwip/test/unit/udp/test_udp.c b/reactos/lib/drivers/lwip/test/unit/udp/test_udp.c index d9b407e03b0..a2f02af06f9 100644 --- a/reactos/lib/drivers/lwip/test/unit/udp/test_udp.c +++ b/reactos/lib/drivers/lwip/test/unit/udp/test_udp.c @@ -56,17 +56,6 @@ START_TEST(test_udp_new_remove) } END_TEST -START_TEST(test_udp_remove) -{ - struct udp_pcb* pcb; - LWIP_UNUSED_ARG(_i); - - pcb = NULL; - //pcb = udp_new(); - //fail_unless(pcb != NULL); -} -END_TEST - /** Create the suite including all tests for this module */ Suite * @@ -74,7 +63,6 @@ udp_suite(void) { TFun tests[] = { test_udp_new_remove, - test_udp_remove }; return create_suite("UDP", tests, sizeof(tests)/sizeof(TFun), udp_setup, udp_teardown); }