Skip to content

Commit 091802a

Browse files
authored
Merge pull request me-no-dev#64 from matt123p/fix-crash-on-fin
Fix crash caused by a race condition when the _lwip_fin function is called
2 parents f8e97b4 + 911414e commit 091802a

File tree

1 file changed

+27
-26
lines changed

1 file changed

+27
-26
lines changed

src/AsyncTCP.cpp

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ typedef struct {
7878

7979
static xQueueHandle _async_queue;
8080
static TaskHandle_t _async_service_task_handle = NULL;
81+
static tcp_pcb * pcb_recently_closed = NULL;
8182

8283
static inline bool _init_async_event_queue(){
8384
if(!_async_queue){
@@ -327,7 +328,6 @@ static int8_t _tcp_accept(void * arg, AsyncClient * client) {
327328
typedef struct {
328329
struct tcpip_api_call_data call;
329330
tcp_pcb * pcb;
330-
AsyncClient * client;
331331
int8_t err;
332332
union {
333333
struct {
@@ -352,39 +352,39 @@ typedef struct {
352352
static err_t _tcp_output_api(struct tcpip_api_call_data *api_call_msg){
353353
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
354354
msg->err = ERR_CONN;
355-
if(msg->client && msg->client->pcb() == msg->pcb){
355+
if(msg->pcb != pcb_recently_closed) {
356356
msg->err = tcp_output(msg->pcb);
357357
}
358+
pcb_recently_closed = NULL;
358359
return msg->err;
359360
}
360361

361-
static esp_err_t _tcp_output(tcp_pcb * pcb, AsyncClient * client) {
362+
static esp_err_t _tcp_output(tcp_pcb * pcb) {
362363
if(!pcb){
363364
return ERR_CONN;
364365
}
365366
tcp_api_call_t msg;
366367
msg.pcb = pcb;
367-
msg.client = client;
368368
tcpip_api_call(_tcp_output_api, (struct tcpip_api_call_data*)&msg);
369369
return msg.err;
370370
}
371371

372372
static err_t _tcp_write_api(struct tcpip_api_call_data *api_call_msg){
373373
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
374374
msg->err = ERR_CONN;
375-
if(msg->client && msg->client->pcb() == msg->pcb){
375+
if(msg->pcb != pcb_recently_closed) {
376376
msg->err = tcp_write(msg->pcb, msg->write.data, msg->write.size, msg->write.apiflags);
377377
}
378+
pcb_recently_closed = NULL;
378379
return msg->err;
379380
}
380381

381-
static esp_err_t _tcp_write(tcp_pcb * pcb, const char* data, size_t size, uint8_t apiflags, AsyncClient * client) {
382+
static esp_err_t _tcp_write(tcp_pcb * pcb, const char* data, size_t size, uint8_t apiflags) {
382383
if(!pcb){
383384
return ERR_CONN;
384385
}
385386
tcp_api_call_t msg;
386387
msg.pcb = pcb;
387-
msg.client = client;
388388
msg.write.data = data;
389389
msg.write.size = size;
390390
msg.write.apiflags = apiflags;
@@ -395,20 +395,20 @@ static esp_err_t _tcp_write(tcp_pcb * pcb, const char* data, size_t size, uint8_
395395
static err_t _tcp_recved_api(struct tcpip_api_call_data *api_call_msg){
396396
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
397397
msg->err = ERR_CONN;
398-
if(msg->client && msg->client->pcb() == msg->pcb){
398+
if(msg->pcb != pcb_recently_closed) {
399399
msg->err = 0;
400400
tcp_recved(msg->pcb, msg->received);
401401
}
402+
pcb_recently_closed = NULL;
402403
return msg->err;
403404
}
404405

405-
static esp_err_t _tcp_recved(tcp_pcb * pcb, size_t len, AsyncClient * client) {
406+
static esp_err_t _tcp_recved(tcp_pcb * pcb, size_t len) {
406407
if(!pcb){
407408
return ERR_CONN;
408409
}
409410
tcp_api_call_t msg;
410411
msg.pcb = pcb;
411-
msg.client = client;
412412
msg.received = len;
413413
tcpip_api_call(_tcp_recved_api, (struct tcpip_api_call_data*)&msg);
414414
return msg.err;
@@ -417,39 +417,39 @@ static esp_err_t _tcp_recved(tcp_pcb * pcb, size_t len, AsyncClient * client) {
417417
static err_t _tcp_close_api(struct tcpip_api_call_data *api_call_msg){
418418
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
419419
msg->err = ERR_CONN;
420-
if(!msg->client || msg->client->pcb() == msg->pcb){
420+
if(msg->pcb != pcb_recently_closed) {
421421
msg->err = tcp_close(msg->pcb);
422422
}
423+
pcb_recently_closed = NULL;
423424
return msg->err;
424425
}
425426

426-
static esp_err_t _tcp_close(tcp_pcb * pcb, AsyncClient * client) {
427+
static esp_err_t _tcp_close(tcp_pcb * pcb) {
427428
if(!pcb){
428429
return ERR_CONN;
429430
}
430431
tcp_api_call_t msg;
431432
msg.pcb = pcb;
432-
msg.client = client;
433433
tcpip_api_call(_tcp_close_api, (struct tcpip_api_call_data*)&msg);
434434
return msg.err;
435435
}
436436

437437
static err_t _tcp_abort_api(struct tcpip_api_call_data *api_call_msg){
438438
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
439439
msg->err = ERR_CONN;
440-
if(!msg->client || msg->client->pcb() == msg->pcb){
440+
if(msg->pcb != pcb_recently_closed) {
441441
tcp_abort(msg->pcb);
442442
}
443+
pcb_recently_closed = NULL;
443444
return msg->err;
444445
}
445446

446-
static esp_err_t _tcp_abort(tcp_pcb * pcb, AsyncClient * client) {
447+
static esp_err_t _tcp_abort(tcp_pcb * pcb) {
447448
if(!pcb){
448449
return ERR_CONN;
449450
}
450451
tcp_api_call_t msg;
451452
msg.pcb = pcb;
452-
msg.client = client;
453453
tcpip_api_call(_tcp_abort_api, (struct tcpip_api_call_data*)&msg);
454454
return msg.err;
455455
}
@@ -697,14 +697,14 @@ bool AsyncClient::connect(const char* host, uint16_t port){
697697

698698
void AsyncClient::close(bool now){
699699
if(_pcb){
700-
_tcp_recved(_pcb, _rx_ack_len, this);
700+
_tcp_recved(_pcb, _rx_ack_len);
701701
}
702702
_close();
703703
}
704704

705705
int8_t AsyncClient::abort(){
706706
if(_pcb) {
707-
_tcp_abort(_pcb, this);
707+
_tcp_abort(_pcb);
708708
_pcb = NULL;
709709
}
710710
return ERR_ABRT;
@@ -727,7 +727,7 @@ size_t AsyncClient::add(const char* data, size_t size, uint8_t apiflags) {
727727
}
728728
size_t will_send = (room < size) ? room : size;
729729
int8_t err = ERR_OK;
730-
err = _tcp_write(_pcb, data, will_send, apiflags, this);
730+
err = _tcp_write(_pcb, data, will_send, apiflags);
731731
if(err != ERR_OK) {
732732
return 0;
733733
}
@@ -736,7 +736,7 @@ size_t AsyncClient::add(const char* data, size_t size, uint8_t apiflags) {
736736

737737
bool AsyncClient::send(){
738738
int8_t err = ERR_OK;
739-
err = _tcp_output(_pcb, this);
739+
err = _tcp_output(_pcb);
740740
if(err == ERR_OK){
741741
_pcb_busy = true;
742742
_pcb_sent_at = millis();
@@ -749,7 +749,7 @@ size_t AsyncClient::ack(size_t len){
749749
if(len > _rx_ack_len)
750750
len = _rx_ack_len;
751751
if(len){
752-
_tcp_recved(_pcb, len, this);
752+
_tcp_recved(_pcb, len);
753753
}
754754
_rx_ack_len -= len;
755755
return len;
@@ -759,7 +759,7 @@ void AsyncClient::ackPacket(struct pbuf * pb){
759759
if(!pb){
760760
return;
761761
}
762-
_tcp_recved(_pcb, pb->len, this);
762+
_tcp_recved(_pcb, pb->len);
763763
pbuf_free(pb);
764764
}
765765

@@ -778,7 +778,7 @@ int8_t AsyncClient::_close(){
778778
tcp_err(_pcb, NULL);
779779
tcp_poll(_pcb, NULL, 0);
780780
_tcp_clear_events(this);
781-
err = _tcp_close(_pcb, this);
781+
err = _tcp_close(_pcb);
782782
if(err != ERR_OK) {
783783
err = abort();
784784
}
@@ -840,6 +840,7 @@ int8_t AsyncClient::_lwip_fin(tcp_pcb* pcb, int8_t err) {
840840
if(tcp_close(_pcb) != ERR_OK) {
841841
tcp_abort(_pcb);
842842
}
843+
pcb_recently_closed = _pcb;
843844
_pcb = NULL;
844845
return ERR_OK;
845846
}
@@ -880,7 +881,7 @@ int8_t AsyncClient::_recv(tcp_pcb* pcb, pbuf* pb, int8_t err) {
880881
if(!_ack_pcb) {
881882
_rx_ack_len += b->len;
882883
} else if(_pcb) {
883-
_tcp_recved(_pcb, b->len, this);
884+
_tcp_recved(_pcb, b->len);
884885
}
885886
pbuf_free(b);
886887
}
@@ -1227,7 +1228,7 @@ void AsyncServer::begin(){
12271228
err = _tcp_bind(_pcb, &local_addr, _port);
12281229

12291230
if (err != ERR_OK) {
1230-
_tcp_close(_pcb, NULL);
1231+
_tcp_close(_pcb);
12311232
log_e("bind error: %d", err);
12321233
return;
12331234
}
@@ -1246,7 +1247,7 @@ void AsyncServer::end(){
12461247
if(_pcb){
12471248
tcp_arg(_pcb, NULL);
12481249
tcp_accept(_pcb, NULL);
1249-
_tcp_abort(_pcb, NULL);
1250+
_tcp_abort(_pcb);
12501251
_pcb = NULL;
12511252
}
12521253
}

0 commit comments

Comments
 (0)