mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-12 01:53:07 +03:00
lwIP-v2: new patch to randomize tcp source ports (#5906)
ref: d-a-v/esp82xx-nonos-linklayer#31 origin: #5902 me-no-dev/ESPAsyncTCP#108 Following the links above is instructive. To summarize: * currently and from a long time lwIP tcp client connections always uses the same tcp source port number right after boot * this port number is increased everytime a new one is needed (= new tcp client connection) (to be noted, linux has the same increasing behavior) * when connecting to the same server (right after boot), the triplet (esp-ip-address, source port, destination port) are the same, and may hit remote server list of sockets in time-wait-state (previous connection unproperly closed from the same esp). Consequently the new connection fails when it happens. * this is happening only when debugging (esp reboots often, in less time than time-wait expiration), so the nasty effect is amplified especially when bugs are being chased * efforts had been done when espressif's lwIP implementation wasn't open source, with WiFiClient::setLocalPortStart() #632 but it must be explicitely called with a different random number at every reboot. Efficient but not ideal. This PR uses espressif firmware's r_rand() everytime a new local source port is needed. A different source port number is now showed by tcpdump right after boot. Source port range and duplication is verified everytime in lwIP's src/core/tcp.c:tcp_new_port(). It is implemented as a local patch for upstream lwIP so it is valid not only with WiFiClient but also with @me-no-dev's Async libraries (they don't use WiFiClient). WiFiClient::setLocalPortStart() is still usable with the same effects as before.
This commit is contained in:
@ -18,7 +18,11 @@
|
||||
#define ULWIPDEBUG 0 // 0 or 1 (trigger lwip debug)
|
||||
#define ULWIPASSERT 0 // 0 or 1 (trigger lwip self-check, 0 saves flash)
|
||||
|
||||
#if ARDUINO
|
||||
#define STRING_IN_FLASH 1 // *print("fmt is stored in flash")
|
||||
#else
|
||||
#define STRING_IN_FLASH 0 // *print("fmt is stored in flash")
|
||||
#endif
|
||||
|
||||
#define ROTBUFLEN_BIT 11 // (UDEBUGSTORE=1) doprint()'s buffer: 11=2048B
|
||||
|
||||
@ -39,7 +43,9 @@ extern "C"
|
||||
void (*phy_capture) (int netif_idx, const char* data, size_t len, int out, int success);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#if ARDUINO
|
||||
#include <sys/pgmspace.h>
|
||||
#endif
|
||||
|
||||
#if UDEBUG && UDEBUGSTORE
|
||||
#warning use 'doprint_allow=1' right after Serial is enabled
|
||||
@ -94,6 +100,7 @@ int doprint_minus (const char* format, ...) __attribute__ ((format (printf, 1, 2
|
||||
#define uprint(x...) do { (void)0; } while (0)
|
||||
#endif
|
||||
|
||||
#if ARDUINO
|
||||
#define udoassert(assertion...) \
|
||||
do { if ((assertion) == 0) { \
|
||||
static const char assrt[] ICACHE_RODATA_ATTR STORE_ATTR = #assertion " wrong@"; \
|
||||
@ -104,6 +111,9 @@ do { if ((assertion) == 0) { \
|
||||
os_printf_plus(assrt_line, __LINE__); \
|
||||
uhalt(); \
|
||||
} } while (0)
|
||||
#else
|
||||
#define udoassert(assertion...) do { if ((assertion) == 0) { os_printf("assert fail: " #assertion " @%s:%d\n", __FILE__, __LINE__); uhalt(); } } while (0)
|
||||
#endif
|
||||
|
||||
#if UNDEBUG
|
||||
#define uassert(assertion...) do { (void)0; } while (0)
|
||||
|
Reference in New Issue
Block a user