I’ve built-in lwIP into my iOS Packet Tunnel Supplier. Most web sites load efficiently, however for some websites the web page masses as much as ~60–80% after which Safari out of the blue exhibits:
“Safari can not open the web page as a result of it couldn’t set up a safe connection to the server.”
To debug this, I enabled lwIP stats and seen the next logs through the failure:
[lwIP] +-------------------------------+
[lwIP] | 4 | 5 | 0x00 | 40 | (v, hl, tos, len)
[lwIP] +-------------------------------+
[lwIP] | 0 |010| 0 | (id, flags, offset)
[lwIP] +-------------------------------+
[lwIP] | 64 | 6 | 0x722d | (ttl, proto, chksum)
[lwIP] +-------------------------------+
[lwIP] | 100 | 64 | 0 | 1 | (src)
[lwIP] +-------------------------------+
[lwIP] | 100 | 96 | 0 | 2 | (dest)
[lwIP] +-------------------------------+
[lwIP] ip4_input: p->len 40 p->tot_len 40
***** [LWIP] to shut connection referred to as from tcp_connection_closed_from_c
[lwIP] tcp_close: closing in
[lwIP] State: ESTABLISHED
[lwIP] tcp_enqueue_flags: queueing 529185:529186 (0x1)
[lwIP] tcp_pcb_purge
[lwIP] tcp_pcb_purge: not all knowledge despatched
[lwIP] MEMP_NUM_TCP_PCB: 64
[lwIP] check_resources_simple check_resources_simple: TCP_PCB=1/64,
[lwIP] TCP_SEG: 0/211 (errors: 0)
[lwIP] PBUF_POOL: 0/128 (errors: 0)
[lwIP] Reminiscence: used=0, max=261340, errors=150
[lwIP] TCP_PCB pool: used=1, max=12, errors=0
[lwIP] ip_input: iphdr->dest 0x2006064 netif->ip_addr 0x1006064 (0x64, 0x64, 0x2006000)
[lwIP] ip4_input: packet accepted on interface v0
[lwIP] ip4_input:
[lwIP] IP header:
[lwIP] +-------------------------------+
[lwIP] | 4 | 5 | 0x00 | 40 | (v, hl, tos, len)
[lwIP] +-------------------------------+
[lwIP] | 0 |010| 0 | (id, flags, offset)
[lwIP] +-------------------------------+
[lwIP] | 64 | 6 | 0x722d | (ttl, proto, chksum)
[lwIP] +-------------------------------+
[lwIP] | 100 | 64 | 0 | 1 | (src)
[lwIP] +-------------------------------+
[lwIP] | 100 | 96 | 0 | 2 | (dest)
[lwIP] +-------------------------------+
[lwIP] ip4_input: p->len 40 p->tot_len 40
***** [LWIP] to shut connection referred to as from tcp_connection_closed_from_c
[lwIP] tcp_close: closing in
[lwIP] State: ESTABLISHED
[lwIP] tcp_enqueue_flags: queueing 160285:160286 (0x1)
[lwIP] tcp_pcb_purge
[lwIP] tcp_pcb_purge: not all knowledge despatched
I additionally incessantly see logs indicating tcp_write
failures as a consequence of inadequate buffer:
[lwIP] 📊 Earlier than tcp_write:
[lwIP] Knowledge size: 4096 bytes
[lwIP] Ship buffer accessible: 1743 bytes
[lwIP] Ship queue size: 44
[lwIP] MSS: 1460 bytes
[lwIP] ❌ Not sufficient ship buffer: want 4096, have 1743
[lwIP] tcp_write failed: -1
It looks like lwIP is closing the connection earlier than all knowledge is absolutely despatched, presumably as a consequence of reminiscence or buffer constraints.
Connected my lwipopts.h
#ifndef LWIP_LWIPOPTS_H
#outline LWIP_LWIPOPTS_H
// No OS integration
#outline NO_SYS 1
#outline SYS_LIGHTWEIGHT_PROT 0
// Allow uncooked API, disable sockets/netconn
#outline LWIP_RAW 1
#outline LWIP_NETCONN 0
#outline LWIP_SOCKET 0
// IPv4 solely (except you explicitly allow IPv6 help)
#outline LWIP_IPV4 1
#outline LWIP_IPV6 0
#outline LWIP_HAVE_SLIPIF 0
#outline LWIP_TIMERS 1
#outline LWIP_TIMEVAL_PRIVATE 0 // So it makes use of system timeval
#outline MEMP_NUM_TCP_PCB 64
// Reminiscence alignment (iOS = 4 bytes)
#outline MEM_ALIGNMENT 4
#outline MEM_SIZE (256 * 1024) // larger heap for bigger buffers
// TCP configuration
#outline LWIP_TCP 1
#outline TCP_TTL 255
#outline TCP_QUEUE_OOSEQ 1
#outline TCP_MSS 1460
#outline TCP_MAXRTX 6
#outline TCP_SYNMAXRTX 4
#outline MEMP_NUM_TCP_SEG (TCP_SND_QUEUELEN + 32)
#outline TCP_SND_QUEUELEN (4 * TCP_SND_BUF / TCP_MSS) // really helpful components
#outline TCP_SND_BUF 65535
#outline TCP_WND 65535
// For those who perceive the reminiscence tradeoffs and nonetheless need to suppress the warning:
// #outline LWIP_DISABLE_TCP_SANITY_CHECKS 1
//#outline MEMP_NUM_TCP_SEG (4 * TCP_SND_BUF / TCP_MSS)
// PBUF pool
#outline PBUF_POOL_SIZE 128
#outline PBUF_POOL_BUFSIZE (TCP_MSS + 40) // MSS + TCP/IP headers
// Community interface
#outline LWIP_NETIF_STATUS_CALLBACK 1
#outline LWIP_NETIF_LINK_CALLBACK 1
#outline LWIP_NETIF_LOOPBACK 0
// IP choices
#outline IP_FORWARD 0
#outline IP_REASSEMBLY 1
#outline IP_FRAG 1
// ARP
#outline LWIP_ARP 1
#outline ARP_TABLE_SIZE 10
#outline ARP_QUEUEING 1
// UDP (non-obligatory)
#outline LWIP_UDP 1
#outline LWIP_UDPLITE 0
#outline UDP_TTL 255
// ICMP (non-obligatory for ping, and many others.)
#outline LWIP_ICMP 1
#outline ICMP_TTL 255
// DHCP/DNS (disabled except used)
#outline LWIP_DHCP 0
#outline LWIP_DNS 0
// Debugging
#outline LWIP_DEBUG 1
#outline IP_DEBUG LWIP_DBG_ON
#outline LWIP_DBG_TYPES_ON LWIP_DBG_ON
#outline LWIP_STATS 1
#outline MEMP_STATS 1 // ✅ ADDED: Allow reminiscence pool stats
// Particular debug choices
#outline IP_DEBUG LWIP_DBG_ON
#outline TCP_DEBUG LWIP_DBG_ON
#outline TCP_OUTPUT_DEBUG LWIP_DBG_ON
#outline MEMP_DEBUG LWIP_DBG_ON
#outline LWIP_DBG_TYPES_ON LWIP_DBG_ON
// ✅ ADDED: Socket particular choices
#outline LWIP_SO_RCVTIMEO 1
#outline LWIP_SO_SNDTIMEO 1
#outline SO_REUSE 1
// ✅ ADDED: Connection administration
#outline TCP_LISTEN_BACKLOG 1
#outline LWIP_TCP_KEEPALIVE 1
#endif /* LWIP_LWIPOPTS_H */
Questions:
- Has anybody confronted this problem the place Safari drops the connection mid-way when utilizing lwIP inside a Packet Tunnel Supplier?
- May this be brought on by lwIP buffer exhaustion (
snd_buf
,TCP_SND_QUEUELEN
, and many others.) or improper dealing with of partial writes? - What configuration tweaks (e.g.,
MEMP_NUM_TCP_SEG
,TCP_SND_BUF
,TCP_SND_QUEUELEN
, and many others.) or greatest practices ought to I apply to keep away from these untimely connection closures?
Any inputs or strategies can be very useful.