mirror of
https://github.com/reactos/reactos.git
synced 2024-08-08 12:18:13 +00:00
[LWIP]
- Properly sync to lwIP 1.4.0 - No code changes (except unit tests) svn path=/trunk/; revision=54302
This commit is contained in:
parent
64e1212557
commit
2506e5967c
|
@ -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
|
HISTORY
|
||||||
|
|
||||||
(CVS HEAD)
|
(CVS HEAD)
|
||||||
|
|
||||||
* [Enter new changes just after this line - do not remove this line]
|
* [Enter new changes just after this line - do not remove this line]
|
||||||
|
|
||||||
|
++ New features:
|
||||||
|
|
||||||
|
|
||||||
|
++ Bugfixes:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(STABLE-1.4.0)
|
||||||
|
|
||||||
++ New features:
|
++ 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)
|
2010-07-12: Simon Goldschmidt (patch by Stephane Lesage)
|
||||||
* ip.c, udp.c/.h, pbuf.h, sockets.c: task #10495: Added support for
|
* ip.c, udp.c/.h, pbuf.h, sockets.c: task #10495: Added support for
|
||||||
IP_MULTICAST_LOOP at socket- and raw-API level.
|
IP_MULTICAST_LOOP at socket- and raw-API level.
|
||||||
|
@ -229,6 +240,137 @@ HISTORY
|
||||||
|
|
||||||
++ Bugfixes:
|
++ 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
|
2010-07-16: Kieran Mansley
|
||||||
* msg_in.c: Fixed SNMP ASN constant defines to not use ! operator
|
* msg_in.c: Fixed SNMP ASN constant defines to not use ! operator
|
||||||
|
|
||||||
|
|
|
@ -111,11 +111,16 @@ with newer versions.
|
||||||
* Added const char* name to mem- and memp-stats for easier debugging.
|
* Added const char* name to mem- and memp-stats for easier debugging.
|
||||||
|
|
||||||
* Calculate the TCP/UDP checksum while copying to only fetch data once:
|
* 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
|
* Added SO_REUSE_RXTOALL to pass received UDP broadcast/multicast packets to
|
||||||
more than one pcb.
|
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
|
++ Major bugfixes/improvements
|
||||||
|
|
||||||
* Implemented tcp_shutdown() to only shut down one end of a connection
|
* Implemented tcp_shutdown() to only shut down one end of a connection
|
||||||
|
|
|
@ -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()
|
the application may use the polling functionality to call tcp_write()
|
||||||
again when the connection has been idle for a while.
|
again when the connection has been idle for a while.
|
||||||
|
|
||||||
- void tcp_poll(struct tcp_pcb *pcb, u8_t interval,
|
- void tcp_poll(struct tcp_pcb *pcb,
|
||||||
err_t (* poll)(void *arg, struct tcp_pcb *tpcb))
|
err_t (* poll)(void *arg, struct tcp_pcb *tpcb),
|
||||||
|
u8_t interval)
|
||||||
|
|
||||||
Specifies the polling interval and the callback function that should
|
Specifies the polling interval and the callback function that should
|
||||||
be called to poll the application. The interval is specified in
|
be called to poll the application. The interval is specified in
|
||||||
|
|
|
@ -123,18 +123,6 @@ The following functions must be implemented by the sys_arch:
|
||||||
sys_arch_mbox_fetch(mbox,msg,1)
|
sys_arch_mbox_fetch(mbox,msg,1)
|
||||||
although this would introduce unnecessary delays.
|
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
|
If threads are supported by the underlying operating system and if
|
||||||
such functionality is needed in lwIP, the following function will have
|
such functionality is needed in lwIP, the following function will have
|
||||||
to be implemented as well:
|
to be implemented as well:
|
||||||
|
|
|
@ -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_listen_input(struct tcp_pcb_listen *pcb);
|
||||||
static err_t tcp_timewait_input(struct tcp_pcb *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 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
|
* the segment between the PCBs and passes it on to tcp_process(), which implements
|
||||||
|
|
|
@ -23,7 +23,7 @@ static Suite* create_suite(const char* name, TFun *tests, size_t num_tests, SFun
|
||||||
Suite *s = suite_create(name);
|
Suite *s = suite_create(name);
|
||||||
|
|
||||||
for(i = 0; i < num_tests; i++) {
|
for(i = 0; i < num_tests; i++) {
|
||||||
// Core test case
|
/* Core test case */
|
||||||
TCase *tc_core = tcase_create("Core");
|
TCase *tc_core = tcase_create("Core");
|
||||||
if ((setup != NULL) || (teardown != NULL)) {
|
if ((setup != NULL) || (teardown != NULL)) {
|
||||||
tcase_add_checked_fixture(tc_core, setup, teardown);
|
tcase_add_checked_fixture(tc_core, setup, teardown);
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include "udp/test_udp.h"
|
#include "udp/test_udp.h"
|
||||||
#include "tcp/test_tcp.h"
|
#include "tcp/test_tcp.h"
|
||||||
#include "tcp/test_tcp_oos.h"
|
#include "tcp/test_tcp_oos.h"
|
||||||
|
#include "core/test_mem.h"
|
||||||
|
#include "etharp/test_etharp.h"
|
||||||
|
|
||||||
#include "lwip/init.h"
|
#include "lwip/init.h"
|
||||||
|
|
||||||
|
@ -16,6 +18,8 @@ int main()
|
||||||
udp_suite,
|
udp_suite,
|
||||||
tcp_suite,
|
tcp_suite,
|
||||||
tcp_oos_suite,
|
tcp_oos_suite,
|
||||||
|
mem_suite,
|
||||||
|
etharp_suite,
|
||||||
};
|
};
|
||||||
size_t num = sizeof(suites)/sizeof(void*);
|
size_t num = sizeof(suites)/sizeof(void*);
|
||||||
LWIP_ASSERT("No suites defined", num > 0);
|
LWIP_ASSERT("No suites defined", num > 0);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "tcp_helper.h"
|
#include "tcp_helper.h"
|
||||||
|
|
||||||
#include "lwip/tcp.h"
|
#include "lwip/tcp_impl.h"
|
||||||
#include "lwip/stats.h"
|
#include "lwip/stats.h"
|
||||||
#include "lwip/pbuf.h"
|
#include "lwip/pbuf.h"
|
||||||
#include "lwip/inet_chksum.h"
|
#include "lwip/inet_chksum.h"
|
||||||
|
@ -27,7 +27,6 @@ tcp_remove(struct tcp_pcb* pcb_list)
|
||||||
void
|
void
|
||||||
tcp_remove_all(void)
|
tcp_remove_all(void)
|
||||||
{
|
{
|
||||||
//tcp_remove(tcp_bound_pcbs);
|
|
||||||
tcp_remove(tcp_listen_pcbs.pcbs);
|
tcp_remove(tcp_listen_pcbs.pcbs);
|
||||||
tcp_remove(tcp_active_pcbs);
|
tcp_remove(tcp_active_pcbs);
|
||||||
tcp_remove(tcp_tw_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 */
|
/** Create a TCP segment usable for passing to tcp_input */
|
||||||
struct pbuf*
|
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,
|
u16_t src_port, u16_t dst_port, void* data, size_t data_len,
|
||||||
u32_t seqno, u32_t ackno, u8_t headerflags)
|
u32_t seqno, u32_t ackno, u8_t headerflags)
|
||||||
{
|
{
|
||||||
struct pbuf* p;
|
struct pbuf* p;
|
||||||
struct ip_hdr* iphdr;
|
struct ip_hdr* iphdr;
|
||||||
struct tcp_hdr* tcphdr;
|
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);
|
p = pbuf_alloc(PBUF_RAW, pbuf_len, PBUF_POOL);
|
||||||
EXPECT_RETNULL(p != NULL);
|
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);
|
tcphdr->ackno = htonl(ackno);
|
||||||
TCPH_HDRLEN_SET(tcphdr, sizeof(struct tcp_hdr)/4);
|
TCPH_HDRLEN_SET(tcphdr, sizeof(struct tcp_hdr)/4);
|
||||||
TCPH_FLAGS_SET(tcphdr, headerflags);
|
TCPH_FLAGS_SET(tcphdr, headerflags);
|
||||||
tcphdr->wnd = htonl(TCP_WND);
|
tcphdr->wnd = htons(TCP_WND);
|
||||||
|
|
||||||
/* copy data */
|
/* copy data */
|
||||||
memcpy((char*)tcphdr + sizeof(struct tcp_hdr), data, data_len);
|
memcpy((char*)tcphdr + sizeof(struct tcp_hdr), data, data_len);
|
||||||
|
|
||||||
/* calculate checksum */
|
/* 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);
|
IP_PROTO_TCP, p->tot_len);
|
||||||
|
|
||||||
pbuf_header(p, sizeof(struct ip_hdr));
|
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 */
|
/** Safely bring a tcp_pcb into the requested state */
|
||||||
void
|
void
|
||||||
tcp_set_state(struct tcp_pcb* pcb, enum tcp_state state, struct ip_addr* local_ip,
|
tcp_set_state(struct tcp_pcb* pcb, enum tcp_state state, ip_addr_t* local_ip,
|
||||||
struct ip_addr* remote_ip, u16_t local_port, u16_t remote_port)
|
ip_addr_t* remote_ip, u16_t local_port, u16_t remote_port)
|
||||||
{
|
{
|
||||||
/* @todo: are these all states? */
|
/* @todo: are these all states? */
|
||||||
/* @todo: remove from previous list */
|
/* @todo: remove from previous list */
|
||||||
|
@ -194,3 +194,20 @@ test_tcp_new_counters_pcb(struct test_tcp_counters* counters)
|
||||||
}
|
}
|
||||||
return pcb;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -21,16 +21,18 @@ struct test_tcp_counters {
|
||||||
/* Helper functions */
|
/* Helper functions */
|
||||||
void tcp_remove_all(void);
|
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,
|
u16_t src_port, u16_t dst_port, void* data, size_t data_len,
|
||||||
u32_t seqno, u32_t ackno, u8_t headerflags);
|
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,
|
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);
|
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,
|
void tcp_set_state(struct tcp_pcb* pcb, enum tcp_state state, ip_addr_t* local_ip,
|
||||||
struct ip_addr* remote_ip, u16_t local_port, u16_t remote_port);
|
ip_addr_t* remote_ip, u16_t local_port, u16_t remote_port);
|
||||||
void test_tcp_counters_err(void* arg, err_t err);
|
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);
|
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);
|
struct tcp_pcb* test_tcp_new_counters_pcb(struct test_tcp_counters* counters);
|
||||||
|
|
||||||
|
void test_tcp_input(struct pbuf *p, struct netif *inp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "test_tcp.h"
|
#include "test_tcp.h"
|
||||||
|
|
||||||
#include "lwip/tcp.h"
|
#include "lwip/tcp_impl.h"
|
||||||
#include "lwip/stats.h"
|
#include "lwip/stats.h"
|
||||||
#include "tcp_helper.h"
|
#include "tcp_helper.h"
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ START_TEST(test_tcp_recv_inseq)
|
||||||
struct tcp_pcb* pcb;
|
struct tcp_pcb* pcb;
|
||||||
struct pbuf* p;
|
struct pbuf* p;
|
||||||
char data[] = {1, 2, 3, 4};
|
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 data_len;
|
||||||
u16_t remote_port = 0x100, local_port = 0x101;
|
u16_t remote_port = 0x100, local_port = 0x101;
|
||||||
struct netif netif;
|
struct netif netif;
|
||||||
|
@ -76,7 +76,7 @@ START_TEST(test_tcp_recv_inseq)
|
||||||
EXPECT(p != NULL);
|
EXPECT(p != NULL);
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
/* pass the segment to tcp_input */
|
/* pass the segment to tcp_input */
|
||||||
tcp_input(p, &netif);
|
test_tcp_input(p, &netif);
|
||||||
/* check if counters are as expected */
|
/* check if counters are as expected */
|
||||||
EXPECT(counters.close_calls == 0);
|
EXPECT(counters.close_calls == 0);
|
||||||
EXPECT(counters.recv_calls == 1);
|
EXPECT(counters.recv_calls == 1);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "test_tcp_oos.h"
|
#include "test_tcp_oos.h"
|
||||||
|
|
||||||
#include "lwip/tcp.h"
|
#include "lwip/tcp_impl.h"
|
||||||
#include "lwip/stats.h"
|
#include "lwip/stats.h"
|
||||||
#include "tcp_helper.h"
|
#include "tcp_helper.h"
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ tcp_oos_seg_seqno(struct tcp_pcb* pcb, int seg_index)
|
||||||
return 0;
|
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 pcb the pcb to check for ooseq segments
|
||||||
* @param seg_index index of the segment on the ooseq list
|
* @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;
|
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 */
|
/* Setup/teardown functions */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -115,7 +134,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ)
|
||||||
5, 6, 7, 8,
|
5, 6, 7, 8,
|
||||||
9, 10, 11, 12,
|
9, 10, 11, 12,
|
||||||
13, 14, 15, 16};
|
13, 14, 15, 16};
|
||||||
struct ip_addr remote_ip, local_ip;
|
ip_addr_t remote_ip, local_ip;
|
||||||
u16_t data_len;
|
u16_t data_len;
|
||||||
u16_t remote_port = 0x100, local_port = 0x101;
|
u16_t remote_port = 0x100, local_port = 0x101;
|
||||||
struct netif netif;
|
struct netif netif;
|
||||||
|
@ -161,7 +180,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ)
|
||||||
EXPECT(p_fin != NULL);
|
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)) {
|
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 */
|
/* 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 */
|
/* check if counters are as expected */
|
||||||
EXPECT(counters.close_calls == 0);
|
EXPECT(counters.close_calls == 0);
|
||||||
EXPECT(counters.recv_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 */
|
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 9); /* includes FIN */
|
||||||
|
|
||||||
/* pass the segment to tcp_input */
|
/* 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 */
|
/* check if counters are as expected */
|
||||||
EXPECT(counters.close_calls == 0);
|
EXPECT(counters.close_calls == 0);
|
||||||
EXPECT(counters.recv_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 */
|
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
|
||||||
|
|
||||||
/* pass the segment to tcp_input */
|
/* 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 */
|
/* check if counters are as expected */
|
||||||
EXPECT(counters.close_calls == 0);
|
EXPECT(counters.close_calls == 0);
|
||||||
EXPECT(counters.recv_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 */
|
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
|
||||||
|
|
||||||
/* pass the segment to tcp_input */
|
/* 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 */
|
/* check if counters are as expected */
|
||||||
EXPECT(counters.close_calls == 0);
|
EXPECT(counters.close_calls == 0);
|
||||||
EXPECT(counters.recv_calls == 0);
|
EXPECT(counters.recv_calls == 0);
|
||||||
EXPECT(counters.recved_bytes == 0);
|
EXPECT(counters.recved_bytes == 0);
|
||||||
EXPECT(counters.err_calls == 0);
|
EXPECT(counters.err_calls == 0);
|
||||||
/* check ooseq queue */
|
/* 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_seqno(pcb, 0) == 2);
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 6);
|
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
|
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
|
|
||||||
|
|
||||||
/* pass the segment to tcp_input */
|
/* pass the segment to tcp_input */
|
||||||
tcp_input(p_fin, &netif);
|
test_tcp_input(p_fin, &netif);
|
||||||
/* check if counters are as expected */
|
/* check if counters are as expected */
|
||||||
EXPECT(counters.close_calls == 0);
|
EXPECT(counters.close_calls == 0);
|
||||||
EXPECT(counters.recv_calls == 0);
|
EXPECT(counters.recv_calls == 0);
|
||||||
EXPECT(counters.recved_bytes == 0);
|
EXPECT(counters.recved_bytes == 0);
|
||||||
EXPECT(counters.err_calls == 0);
|
EXPECT(counters.err_calls == 0);
|
||||||
/* ooseq queue: unchanged */
|
/* 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_seqno(pcb, 0) == 2);
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 6);
|
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
|
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
|
|
||||||
|
|
||||||
/* pass the segment to tcp_input */
|
/* pass the segment to tcp_input */
|
||||||
tcp_input(pinseq, &netif);
|
test_tcp_input(pinseq, &netif);
|
||||||
/* check if counters are as expected */
|
/* check if counters are as expected */
|
||||||
EXPECT(counters.close_calls == 1);
|
EXPECT(counters.close_calls == 1);
|
||||||
EXPECT(counters.recv_calls == 1);
|
EXPECT(counters.recv_calls == 1);
|
||||||
|
@ -259,7 +274,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
|
||||||
5, 6, 7, 8,
|
5, 6, 7, 8,
|
||||||
9, 10, 11, 12,
|
9, 10, 11, 12,
|
||||||
13, 14, 15, 16};
|
13, 14, 15, 16};
|
||||||
struct ip_addr remote_ip, local_ip;
|
ip_addr_t remote_ip, local_ip;
|
||||||
u16_t data_len;
|
u16_t data_len;
|
||||||
u16_t remote_port = 0x100, local_port = 0x101;
|
u16_t remote_port = 0x100, local_port = 0x101;
|
||||||
struct netif netif;
|
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)
|
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)) {
|
&& (p_15_1 != NULL) && (p_15_1a != NULL) && (pinseqFIN != NULL)) {
|
||||||
/* pass the segment to tcp_input */
|
/* 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 */
|
/* check if counters are as expected */
|
||||||
EXPECT(counters.close_calls == 0);
|
EXPECT(counters.close_calls == 0);
|
||||||
EXPECT(counters.recv_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);
|
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
|
||||||
|
|
||||||
/* pass the segment to tcp_input */
|
/* 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 */
|
/* check if counters are as expected */
|
||||||
EXPECT(counters.close_calls == 0);
|
EXPECT(counters.close_calls == 0);
|
||||||
EXPECT(counters.recv_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);
|
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 8);
|
||||||
|
|
||||||
/* pass the segment to tcp_input */
|
/* 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 */
|
/* check if counters are as expected */
|
||||||
EXPECT(counters.close_calls == 0);
|
EXPECT(counters.close_calls == 0);
|
||||||
EXPECT(counters.recv_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);
|
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 11);
|
||||||
|
|
||||||
/* pass the segment to tcp_input */
|
/* 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 */
|
/* check if counters are as expected */
|
||||||
EXPECT(counters.close_calls == 0);
|
EXPECT(counters.close_calls == 0);
|
||||||
EXPECT(counters.recv_calls == 0);
|
EXPECT(counters.recv_calls == 0);
|
||||||
EXPECT(counters.recved_bytes == 0);
|
EXPECT(counters.recved_bytes == 0);
|
||||||
EXPECT(counters.err_calls == 0);
|
EXPECT(counters.err_calls == 0);
|
||||||
/* check ooseq queue */
|
/* 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_seqno(pcb, 0) == 1);
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(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_seqno(pcb, 1) == 2);
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 1);
|
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 12);
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 2) == 3);
|
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 2) == 11);
|
|
||||||
|
|
||||||
/* pass the segment to tcp_input */
|
/* pass the segment to tcp_input */
|
||||||
tcp_input(pinseq, &netif);
|
test_tcp_input(pinseq, &netif);
|
||||||
/* check if counters are as expected */
|
/* check if counters are as expected */
|
||||||
EXPECT(counters.close_calls == 0);
|
EXPECT(counters.close_calls == 0);
|
||||||
EXPECT(counters.recv_calls == 1);
|
EXPECT(counters.recv_calls == 1);
|
||||||
|
@ -381,7 +394,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
|
||||||
EXPECT(pcb->ooseq == NULL);
|
EXPECT(pcb->ooseq == NULL);
|
||||||
|
|
||||||
/* pass the segment to tcp_input */
|
/* 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 */
|
/* check if counters are as expected */
|
||||||
EXPECT(counters.close_calls == 0);
|
EXPECT(counters.close_calls == 0);
|
||||||
EXPECT(counters.recv_calls == 1);
|
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);
|
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
|
||||||
|
|
||||||
/* pass the segment to tcp_input */
|
/* 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 */
|
/* check if counters are as expected */
|
||||||
EXPECT(counters.close_calls == 0);
|
EXPECT(counters.close_calls == 0);
|
||||||
EXPECT(counters.recv_calls == 1);
|
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);
|
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
|
||||||
|
|
||||||
/* pass the segment to tcp_input */
|
/* pass the segment to tcp_input */
|
||||||
tcp_input(pinseqFIN, &netif);
|
test_tcp_input(pinseqFIN, &netif);
|
||||||
/* check if counters are as expected */
|
/* check if counters are as expected */
|
||||||
EXPECT(counters.close_calls == 1);
|
EXPECT(counters.close_calls == 1);
|
||||||
EXPECT(counters.recv_calls == 2);
|
EXPECT(counters.recv_calls == 2);
|
||||||
|
@ -421,6 +434,99 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
|
||||||
}
|
}
|
||||||
END_TEST
|
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 */
|
/** Create the suite including all tests for this module */
|
||||||
Suite *
|
Suite *
|
||||||
tcp_oos_suite(void)
|
tcp_oos_suite(void)
|
||||||
|
@ -428,6 +534,7 @@ tcp_oos_suite(void)
|
||||||
TFun tests[] = {
|
TFun tests[] = {
|
||||||
test_tcp_recv_ooseq_FIN_OOSEQ,
|
test_tcp_recv_ooseq_FIN_OOSEQ,
|
||||||
test_tcp_recv_ooseq_FIN_INSEQ,
|
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);
|
return create_suite("TCP_OOS", tests, sizeof(tests)/sizeof(TFun), tcp_oos_setup, tcp_oos_teardown);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,17 +56,6 @@ START_TEST(test_udp_new_remove)
|
||||||
}
|
}
|
||||||
END_TEST
|
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 */
|
/** Create the suite including all tests for this module */
|
||||||
Suite *
|
Suite *
|
||||||
|
@ -74,7 +63,6 @@ udp_suite(void)
|
||||||
{
|
{
|
||||||
TFun tests[] = {
|
TFun tests[] = {
|
||||||
test_udp_new_remove,
|
test_udp_new_remove,
|
||||||
test_udp_remove
|
|
||||||
};
|
};
|
||||||
return create_suite("UDP", tests, sizeof(tests)/sizeof(TFun), udp_setup, udp_teardown);
|
return create_suite("UDP", tests, sizeof(tests)/sizeof(TFun), udp_setup, udp_teardown);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue