Skip to content

Commit 2d58be7

Browse files
authored
TCP: fixes backlog limit handling, and allows ephemeral TCP connections (#7096)
* fix backlog limit handling, and allow ephemeral TCP connections * do not retain empty connections
1 parent 2b640c0 commit 2d58be7

File tree

3 files changed

+35
-33
lines changed

3 files changed

+35
-33
lines changed

libraries/ESP8266WiFi/src/WiFiClient.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ uint8_t WiFiClient::status()
346346

347347
WiFiClient::operator bool()
348348
{
349-
return connected();
349+
return available() || connected();
350350
}
351351

352352
IPAddress WiFiClient::remoteIP()

libraries/ESP8266WiFi/src/WiFiServer.cpp

+9-15
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,14 @@ WiFiClient WiFiServer::available(byte* status) {
125125
if (_unclaimed) {
126126
WiFiClient result(_unclaimed);
127127
#if LWIP_VERSION_MAJOR != 1
128-
_unclaimed->acceptPCB();
129-
tcp_backlog_accepted(_unclaimed->getPCB());
128+
// pcb can be null when peer has already closed the connection
129+
if (_unclaimed->getPCB())
130+
// give permission to lwIP to accept one more peer
131+
tcp_backlog_accepted(_unclaimed->getPCB());
130132
#endif
131133
_unclaimed = _unclaimed->next();
132134
result.setNoDelay(getNoDelay());
133-
DEBUGV("WS:av\r\n");
135+
DEBUGV("WS:av status=%d WCav=%d\r\n", result.status(), result.available());
134136
return result;
135137
}
136138

@@ -187,9 +189,12 @@ long WiFiServer::_accept(tcp_pcb* apcb, long err) {
187189
(void) err;
188190
DEBUGV("WS:ac\r\n");
189191

192+
// always accept new PCB so incoming data can be stored in our buffers even before
193+
// user calls ::available()
194+
ClientContext* client = new ClientContext(apcb, &WiFiServer::_s_discard, this);
195+
190196
#if LWIP_VERSION_MAJOR == 1
191197

192-
ClientContext* client = new ClientContext(apcb, &WiFiServer::_s_discard, this);
193198
tcp_accepted(_listen_pcb);
194199

195200
#else
@@ -198,20 +203,9 @@ long WiFiServer::_accept(tcp_pcb* apcb, long err) {
198203
// http://lwip.100.n7.nabble.com/Problem-re-opening-listening-pbc-tt32484.html#a32494
199204
// https://www.nongnu.org/lwip/2_1_x/group__tcp__raw.html#gaeff14f321d1eecd0431611f382fcd338
200205

201-
// lwip-v2: Tell ClientContext to not accept yet the connection (final 'false' below)
202-
ClientContext* client = new ClientContext(apcb, &WiFiServer::_s_discard, this, false);
203206
// increase lwIP's backlog
204207
tcp_backlog_delayed(apcb);
205208

206-
// Optimization Path:
207-
// when lwip-v1.4 is not allowed anymore,
208-
// - _accept() should not create ClientContext anymore
209-
// - apcb should be stored into some sort of linked list (->_unclaimed)
210-
// (the linked list would store tcp_pcb* instead of ClientContext*)
211-
// (TCP_PCB_EXTARGS might be used for that (lwIP's struct tcp_pcb))
212-
// - on available(), get the pcb back and create the ClientContext
213-
// (this is not done today for better source readability with lwip-1.4 around)
214-
215209
#endif
216210

217211
_unclaimed = slist_append_tail(_unclaimed, client);

libraries/ESP8266WiFi/src/include/ClientContext.h

+25-17
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,9 @@ bool getDefaultPrivateGlobalSyncValue ();
3636
class ClientContext
3737
{
3838
public:
39-
ClientContext(tcp_pcb* pcb, discard_cb_t discard_cb, void* discard_cb_arg, bool acceptNow = true) :
39+
ClientContext(tcp_pcb* pcb, discard_cb_t discard_cb, void* discard_cb_arg) :
4040
_pcb(pcb), _rx_buf(0), _rx_buf_offset(0), _discard_cb(discard_cb), _discard_cb_arg(discard_cb_arg), _refcnt(0), _next(0),
4141
_sync(::getDefaultPrivateGlobalSyncValue())
42-
{
43-
if (acceptNow)
44-
acceptPCB();
45-
}
46-
47-
tcp_pcb* getPCB ()
48-
{
49-
return _pcb;
50-
}
51-
52-
void acceptPCB()
5342
{
5443
tcp_setprio(_pcb, TCP_PRIO_MIN);
5544
tcp_arg(_pcb, this);
@@ -62,6 +51,11 @@ class ClientContext
6251
//keepAlive();
6352
}
6453

54+
tcp_pcb* getPCB ()
55+
{
56+
return _pcb;
57+
}
58+
6559
err_t abort()
6660
{
6761
if(_pcb) {
@@ -302,6 +296,7 @@ class ClientContext
302296

303297
void discard_received()
304298
{
299+
DEBUGV(":dsrcv %d\n", _rx_buf? _rx_buf->tot_len: 0);
305300
if(!_rx_buf) {
306301
return;
307302
}
@@ -360,7 +355,8 @@ class ClientContext
360355

361356
uint8_t state() const
362357
{
363-
if(!_pcb) {
358+
if(!_pcb || _pcb->state == CLOSE_WAIT || _pcb->state == CLOSING) {
359+
// CLOSED for WiFIClient::status() means nothing more can be written
364360
return CLOSED;
365361
}
366362

@@ -587,11 +583,23 @@ class ClientContext
587583
{
588584
(void) pcb;
589585
(void) err;
590-
if(pb == 0) { // connection closed
591-
DEBUGV(":rcl\r\n");
586+
if(pb == 0) {
587+
// connection closed by peer
588+
DEBUGV(":rcl pb=%p sz=%d\r\n", _rx_buf, _rx_buf? _rx_buf->tot_len: -1);
592589
_notify_error();
593-
abort();
594-
return ERR_ABRT;
590+
if (_rx_buf && _rx_buf->tot_len)
591+
{
592+
// there is still something to read
593+
return ERR_OK;
594+
}
595+
else
596+
{
597+
// nothing in receive buffer,
598+
// peer closed = nothing can be written:
599+
// closing in the legacy way
600+
abort();
601+
return ERR_ABRT;
602+
}
595603
}
596604

597605
if(_rx_buf) {

0 commit comments

Comments
 (0)