Some systems need to take into account an RX buffer pool size when
advising an appropriate number of RX pbufs to queue on the ooseq
list. For some systems there is a practical hard limit beyond which
the rx pool becomes exhausted blocking reception of further buffers
until some are freed.
It also helps to be able to consider the available dynamic memory when
advising an appropriate maximum number of bytes to buffer on the ooseq
list.
These decisions can also benefit from knowing the number already
allocated on a particular pcb, so the ooseq tcp segement is passed to
these functions. For example, if the system only wants to allow the
total number of rx pbufs queued on all the ooseq lists to grow by one
and a pcb already has two then it can return three for this call, but
might return one for another call - supporting a greedy allocation
strategy.
Signed-off-by: goldsimon <goldsimon@gmx.de>
Hop-by-Hop, Destination option header structures consist of 2 unsigned char; next option type and header length field.
And TLV(Type-Length-Value) option headers come by the number in header length field.
If the option type in TLV option header is not recognized and 2 MSB is not 0, it is handled as an exception.
Signed-off-by: goldsimon <goldsimon@gmx.de>
Hop-by-Hop, Destination option header structures consist of 2 unsigned char; next option type and header length field.
And TLV(Type-Length-Value) option headers come by the number in header length field.
If the option type in TLV option header is not recognized and 2 MSB is not 0, it is handled as an exception.
Signed-off-by: goldsimon <goldsimon@gmx.de>
For this, convert 'u8_t nexth' to a pointer and change 'icmp6_param_problem()' to take a pointer, not an offset number
Signed-off-by: goldsimon <goldsimon@gmx.de>
TCP SACKs were removed after some changes in the ooseq queue,
but before all unneeded packets were removed from it.
Because of that, we would sometimes include SACKs
for data already delivered in-order.
Signed-off-by: goldsimon <goldsimon@gmx.de>
This problem would appear to have only affected systems with multiple
interfaces. It was noted causing tcp resets when the pcb was lost, and there
might have been other associated problems.
Signed-off-by: Dirk Ziegelmeier <dirk@ziegelmeier.net>
There were a couple cases in-between that could cause an exit from
tcp_output which don't use useg. With large send buffers, pcb->unacked
may be large and calculating useg is wasted in these exit cases
Some compilers may be re-ordering this already, but it doesn't hurt to
correctly arrange the code
This re-works the persist timer to have the following behavior:
1) Only start persist timer when a buffered segment doesn't fit within
the current window and there is no in-fligh data. Previously, the
persist timer was always started when the window went to zero even
if there was no buffered data (since timer was managed in receive
pathway rather than transmit pathway)
2) Upon first fire of persist timer, fill the remaining window if
non-zero by splitting the unsent segment. If split segment is sent,
persist timer is stopped, RTO timer is now ensuring reliable window
updates
3) If window is already zero when persist timer fires, send 1 byte probe
4) Persist timer and zero window probe should only be active when the
following are true:
* no in-flight data (pcb->unacked == NULL)
* when there is buffered data (pcb->unsent != NULL)
* when pcb->unsent->len > pcb->snd_wnd
lwip_itoa would output the number 0 as \0. This fixes the issue by
adding a special check before the normal conversion loop
This was found via shell cmd idxtoname and win32 port. "lo0" should
be returned for index 1
- add a better-documented static function tcp_output_segment_busy
- try to reduce the number of checks
- tcp_rexmit_rto: iterate pcb->unacked only once
- no need to check for ref==1 in tcp_rexmit_fast when tcp_rexmit does
- call tcp_rexmit_fast if dupacks >= 3 (not == 3) and use TF_INFR flag to guard the fast-rexmit case (that way, it's triggered again on the next dupack)
There is already a guard in tcp_output_segment() for a pbuf still being
referenced by the netif driver due to deferred transmission, however the callers
are modifying state even when this gives up.
It seems cleaner to have the callers guard this case and avoid modifying their
state.
tcp_rexmit_rto() might better avoid re-transmission of any segments if any of
the unacked segments are deferred, to avoid loading the link further if it is
struggling to flush its buffered writes. Link level queues can be limited on
some devices and need spares for link management.
- expose `altcp_tcp_setup()` so we can wrap altcp over existing tcp pcb.
- avoid calling tcp_close() with NULL pcb.
- free altcp_pcb struct when error callback called.
According to `mqtt_tcp_err_cb()` in src/apps/mqtt/mqtt.c, altcp socket should
work the same way than raw tcp socket. So freeing altcp_pcb ensure this.
The new functions both take size_t as increment/decrement argument instead of s16_t (which needed to be range-checked before conversion everywhere) - in most places, the direction (increment or decrement) is known anyway, so no need to encode it in a sign bit
In tcp_output() there were a number of blocks of code performing
duplicate checks of 'if (seg == NULL)'. This combines them together
to reduce duplicate checks
TCP_OUTPUT_DEBUG and TCP_CWND_DEBUG also don't need to be guarded
by #if/#endif since the LWIP_DEBUGF infrastructure already compiles them
out when LWIP_DEBUG is not defined
The ip6_frag.drop counter is updated before all the code paths calling
goto nullreturn, so let's move updating ip6_frag.drop stats to nullreturn.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
This fixes a couple of occurrences where the src and dst parameters to
ip4_route_src() were swapped. This was most likely due to confusion between
ip_route(src, dst) and ip4_route_src(dst, src)
This was found in a system where LWIP_IPV4_SRC_ROUTING is 0
The UDP case was an application socket bound to INADDR_ANY with
IP_MULTICAST_IF set. Transmits would result in calling ip4_route(dst) where
dst was pcb->local_addr (which was INADDR_ANY) instead of pcb->mcast_ip4.
This resulted in a routing failure
The ICMP issue was found through code analysis only
There were uses of dhcp_release() followed immediately by dhcp_discover() but
dhcp_release() now stops dhcp so discovery would fail, so call dhcp_start()
after release which restarts discovery.
Signed-off-by: Dirk Ziegelmeier <dirk@ziegelmeier.net>
According to commit 1f780e86d5 ("PPP timeouts required depend on the number of allowed PPP sessions"):
Per PPP needs 6 timeouts (AUTH + PAP|CHAP|EAP + LCP + IPCP + IP6CP + PPPoE).
So update the minimal MEMP_NUM_SYS_TIMEOUT setting check accordingly.
Since we have LWIP_NUM_SYS_TIMEOUT_INTERNAL so just switch to use it.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Signed-off-by: goldsimon <goldsimon@gmx.de>
The ip6_addr_t structure may have an addition slot so is not necessarily
the size of an ipv6 address, so some uses of sizeof(ip6_addr_t) were not
correct.
Signed-off-by: goldsimon <goldsimon@gmx.de>
No need to have additional if statement for PBUF_REF/PBUF_ROM.
It can be merged to the existing swtich(type) cases.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Adds partial support for selective acknowledgements (RFC 2018).
This change makes lwIP negotiate SACK support, and include SACK
data in outgoing empty ACK packets. It does not include it
in outgoing packets with data payload.
It also does not add support for handling incoming SACKs.
Signed-off-by: goldsimon <goldsimon@gmx.de>
TCP timestamps were only sent if the remote side
requested it first. This enables the use of timestamps
for outgoing connections as well.
Signed-off-by: goldsimon <goldsimon@gmx.de>
Changes for TCP Appropriate Byte Counting introduce a potential cwnd
rollover by not taking into account integer promotion on tcpwnd_size_t
during inequality comparisions
This fixes the issue by introducing a macro TCP_WND_INC which detects
the rollover correctly and now holds the tcpwnd_size_t at the maximum
value rather than not incrementing the window. This provides a slight
performance improvement by allowing full use of the tcpwnd_size_t number
space for the congestion window
etharp_query() queues packets, instead of sending, if a relevant arp-request is
pending.
Code walks the packet (a pbuf chain) to determine whether any pbufs are marked
'volatile': If so, we cannot simply enqueue the packet, and instead allocate a
new pbuf from RAM, copying the original packet, and enqueueing this new pbuf.
The bug here is that the allocation refers to the tot_len field of a temp pbuf*,
'p', instead of the head, 'q'.
In the case where the first pbuf of the chain is non-volatile but the second pbuf
*is* volatile, then we'll request an allocation that uses the tot_len field of
the second pbuf. If the first pbuf is non-zero length, the allocated pbuf (chain)
will be too small to allow the copy.
Signed-off-by: goldsimon <goldsimon@gmx.de>
All callers pass pbuf_type to pbuf_init_alloced_pbuf(), so make it take
pbuf_type instead of u8_t.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Signed-off-by: goldsimon <goldsimon@gmx.de>
This commit adds a timeout to the zero-window probing (persist timer)
mechanism. LwIP has not historically had a timeout for the persist
timer, leading to unbounded blocking if connection drops during the
zero-window condition
This commit also adds two units test, one to check the RTO timeout
and a second to check the zero-window probe timeout
Fix below build error if LWIP_IPV4 == 0.
cc -g -Wall -DLWIP_DEBUG -pedantic -Werror -Wparentheses -Wsequence-point -Wswitch-default -Wextra -Wundef -Wshadow -Wpointer-arith -Wcast-qual -Wc++-compat -Wwrite-strings -Wold-style-definition -Wcast-align -Wmissing-prototypes -Wredundant-decls -Wnested-externs -Wno-address -Wunreachable-code -Wuninitialized -Wlogical-op -I. -I../../.. -I../../../../lwip/src/include -I../../../ports/unix/port/include -I../../../../mbedtls/include -Wno-redundant-decls -DLWIP_HAVE_MBEDTLS=1 -c ../../../../lwip/src/core/netif.c
../../../../lwip/src/core/netif.c: In function ‘netif_add’:
../../../../lwip/src/core/netif.c:284:7: error: ‘ipaddr’ undeclared (first use in this function)
if (ipaddr == NULL) {
^~~~~~
../../../../lwip/src/core/netif.c:284:7: note: each undeclared identifier is reported only once for each function it appears in
../../../../lwip/src/core/netif.c:285:14: error: implicit declaration of function ‘ip_2_ip4’ [-Werror=implicit-function-declaration]
ipaddr = ip_2_ip4(IP4_ADDR_ANY);
^~~~~~~~
../../../../lwip/src/core/netif.c:285:5: error: nested extern declaration of ‘ip_2_ip4’ [-Werror=nested-externs]
ipaddr = ip_2_ip4(IP4_ADDR_ANY);
^~~~~~
../../../../lwip/src/core/netif.c:285:23: error: ‘IP4_ADDR_ANY’ undeclared (first use in this function)
ipaddr = ip_2_ip4(IP4_ADDR_ANY);
^~~~~~~~~~~~
../../../../lwip/src/core/netif.c:287:7: error: ‘netmask’ undeclared (first use in this function)
if (netmask == NULL) {
^~~~~~~
../../../../lwip/src/core/netif.c:290:7: error: ‘gw’ undeclared (first use in this function)
if (gw == NULL) {
^~
cc1: all warnings being treated as errors
../../Common.allports.mk:94: recipe for target 'netif.o' failed
make: *** [netif.o] Error 1
Fixes: 5967380c20 ("netif_add: avoid passing NULL pointers to subsequent functions")
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Signed-off-by: Dirk Ziegelmeier <dirk@ziegelmeier.net>