From 5754e5dd598f120ea59bf56608fe96bfe942ae39 Mon Sep 17 00:00:00 2001 From: "Sergio R. Caprile" Date: Thu, 3 Aug 2023 13:42:12 -0300 Subject: [PATCH 1/2] fix ARP timeout --- mongoose.c | 4 ++-- src/tcpip/tcpip.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mongoose.c b/mongoose.c index f19eb093..8b9c3705 100644 --- a/mongoose.c +++ b/mongoose.c @@ -8570,7 +8570,7 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t uptime_ms) { // Process timeouts for (struct mg_connection *c = ifp->mgr->conns; c != NULL; c = c->next) { if (c->is_udp || c->is_listening) continue; - if (c->is_connecting || c->is_resolving) continue; + if (!c->is_arplooking && (c->is_connecting || c->is_resolving)) continue; struct connstate *s = (struct connstate *) (c + 1); uint32_t rem_ip; memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t)); @@ -8672,7 +8672,7 @@ void mg_connect_resolved(struct mg_connection *c) { &c->rem)); mg_call(c, MG_EV_RESOLVE, NULL); if (((rem_ip & ifp->mask) == (ifp->ip & ifp->mask))) { - // If we're in the same LAN, fire an ARP lookup. TODO(cpq): handle this! + // If we're in the same LAN, fire an ARP lookup. MG_DEBUG(("%lu ARP lookup...", c->id)); arp_ask(ifp, rem_ip); settmout(c, MIP_TTYPE_ARP); diff --git a/src/tcpip/tcpip.c b/src/tcpip/tcpip.c index 94efbd50..be8819ad 100644 --- a/src/tcpip/tcpip.c +++ b/src/tcpip/tcpip.c @@ -847,7 +847,7 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t uptime_ms) { // Process timeouts for (struct mg_connection *c = ifp->mgr->conns; c != NULL; c = c->next) { if (c->is_udp || c->is_listening) continue; - if (c->is_connecting || c->is_resolving) continue; + if (!c->is_arplooking && (c->is_connecting || c->is_resolving)) continue; struct connstate *s = (struct connstate *) (c + 1); uint32_t rem_ip; memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t)); @@ -949,7 +949,7 @@ void mg_connect_resolved(struct mg_connection *c) { &c->rem)); mg_call(c, MG_EV_RESOLVE, NULL); if (((rem_ip & ifp->mask) == (ifp->ip & ifp->mask))) { - // If we're in the same LAN, fire an ARP lookup. TODO(cpq): handle this! + // If we're in the same LAN, fire an ARP lookup. MG_DEBUG(("%lu ARP lookup...", c->id)); arp_ask(ifp, rem_ip); settmout(c, MIP_TTYPE_ARP); From 5cdf6c1d0521588354d194e9378cc1b89e877fc4 Mon Sep 17 00:00:00 2001 From: "Sergio R. Caprile" Date: Thu, 3 Aug 2023 14:23:14 -0300 Subject: [PATCH 2/2] Add SYN timeout --- mongoose.c | 15 ++++++++++----- src/tcpip/tcpip.c | 15 ++++++++++----- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/mongoose.c b/mongoose.c index 8b9c3705..c33171cc 100644 --- a/mongoose.c +++ b/mongoose.c @@ -7732,8 +7732,9 @@ struct mg_tcpip_driver mg_tcpip_driver_w5500 = {w5500_init, w5500_tx, w5500_rx, #define MIP_TCP_KEEPALIVE_MS 45000 // TCP keep-alive period, ms #endif -#define MIP_TCP_ACK_MS 150 // Timeout for ACKing -#define MIP_TCP_ARP_MS 100 // Timeout for ARP response +#define MIP_TCP_ACK_MS 150 // Timeout for ACKing +#define MIP_TCP_ARP_MS 100 // Timeout for ARP response +#define MIP_TCP_SYN_MS 15000 // Timeout for connection establishment struct connstate { uint32_t seq, ack; // TCP seq/ack counters @@ -7743,6 +7744,7 @@ struct connstate { #define MIP_TTYPE_KEEPALIVE 0 // Connection is idle for long, send keepalive #define MIP_TTYPE_ACK 1 // Peer sent us data, we have to ack it soon #define MIP_TTYPE_ARP 2 // ARP resolve sent, waiting for response +#define MIP_TTYPE_SYN 3 // SYN sent, waiting for response uint8_t tmiss; // Number of keep-alive misses struct mg_iobuf raw; // For TLS only. Incoming raw data }; @@ -7881,6 +7883,7 @@ static void settmout(struct mg_connection *c, uint8_t type) { struct connstate *s = (struct connstate *) (c + 1); unsigned n = type == MIP_TTYPE_ACK ? MIP_TCP_ACK_MS : type == MIP_TTYPE_ARP ? MIP_TCP_ARP_MS + : type == MIP_TTYPE_SYN ? MIP_TCP_SYN_MS : MIP_TCP_KEEPALIVE_MS; s->timer = ifp->now + n; s->ttype = type; @@ -8067,8 +8070,8 @@ static void rx_arp(struct mg_tcpip_if *ifp, struct pkt *pkt) { MG_DEBUG(("%lu ARP resolved %M -> %M", c->id, mg_print_ip4, c->rem.ip, mg_print_mac, s->mac)); c->is_arplooking = 0; - settmout(c, MIP_TTYPE_KEEPALIVE); send_syn(c); + settmout(c, MIP_TTYPE_SYN); } } } @@ -8569,8 +8572,7 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t uptime_ms) { // Process timeouts for (struct mg_connection *c = ifp->mgr->conns; c != NULL; c = c->next) { - if (c->is_udp || c->is_listening) continue; - if (!c->is_arplooking && (c->is_connecting || c->is_resolving)) continue; + if (c->is_udp || c->is_listening || c->is_resolving) continue; struct connstate *s = (struct connstate *) (c + 1); uint32_t rem_ip; memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t)); @@ -8581,6 +8583,8 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t uptime_ms) { mg_htonl(s->seq), mg_htonl(s->ack), "", 0); } else if (s->ttype == MIP_TTYPE_ARP) { mg_error(c, "ARP timeout"); + } else if (s->ttype == MIP_TTYPE_SYN) { + mg_error(c, "Connection timeout"); } else { if (s->tmiss++ > 2) { mg_error(c, "keepalive"); @@ -8694,6 +8698,7 @@ void mg_connect_resolved(struct mg_connection *c) { mg_call(c, MG_EV_CONNECT, NULL); } else { send_syn(c); + settmout(c, MIP_TTYPE_SYN); c->is_connecting = 1; } } diff --git a/src/tcpip/tcpip.c b/src/tcpip/tcpip.c index be8819ad..52a8c139 100644 --- a/src/tcpip/tcpip.c +++ b/src/tcpip/tcpip.c @@ -9,8 +9,9 @@ #define MIP_TCP_KEEPALIVE_MS 45000 // TCP keep-alive period, ms #endif -#define MIP_TCP_ACK_MS 150 // Timeout for ACKing -#define MIP_TCP_ARP_MS 100 // Timeout for ARP response +#define MIP_TCP_ACK_MS 150 // Timeout for ACKing +#define MIP_TCP_ARP_MS 100 // Timeout for ARP response +#define MIP_TCP_SYN_MS 15000 // Timeout for connection establishment struct connstate { uint32_t seq, ack; // TCP seq/ack counters @@ -20,6 +21,7 @@ struct connstate { #define MIP_TTYPE_KEEPALIVE 0 // Connection is idle for long, send keepalive #define MIP_TTYPE_ACK 1 // Peer sent us data, we have to ack it soon #define MIP_TTYPE_ARP 2 // ARP resolve sent, waiting for response +#define MIP_TTYPE_SYN 3 // SYN sent, waiting for response uint8_t tmiss; // Number of keep-alive misses struct mg_iobuf raw; // For TLS only. Incoming raw data }; @@ -158,6 +160,7 @@ static void settmout(struct mg_connection *c, uint8_t type) { struct connstate *s = (struct connstate *) (c + 1); unsigned n = type == MIP_TTYPE_ACK ? MIP_TCP_ACK_MS : type == MIP_TTYPE_ARP ? MIP_TCP_ARP_MS + : type == MIP_TTYPE_SYN ? MIP_TCP_SYN_MS : MIP_TCP_KEEPALIVE_MS; s->timer = ifp->now + n; s->ttype = type; @@ -344,8 +347,8 @@ static void rx_arp(struct mg_tcpip_if *ifp, struct pkt *pkt) { MG_DEBUG(("%lu ARP resolved %M -> %M", c->id, mg_print_ip4, c->rem.ip, mg_print_mac, s->mac)); c->is_arplooking = 0; - settmout(c, MIP_TTYPE_KEEPALIVE); send_syn(c); + settmout(c, MIP_TTYPE_SYN); } } } @@ -846,8 +849,7 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t uptime_ms) { // Process timeouts for (struct mg_connection *c = ifp->mgr->conns; c != NULL; c = c->next) { - if (c->is_udp || c->is_listening) continue; - if (!c->is_arplooking && (c->is_connecting || c->is_resolving)) continue; + if (c->is_udp || c->is_listening || c->is_resolving) continue; struct connstate *s = (struct connstate *) (c + 1); uint32_t rem_ip; memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t)); @@ -858,6 +860,8 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t uptime_ms) { mg_htonl(s->seq), mg_htonl(s->ack), "", 0); } else if (s->ttype == MIP_TTYPE_ARP) { mg_error(c, "ARP timeout"); + } else if (s->ttype == MIP_TTYPE_SYN) { + mg_error(c, "Connection timeout"); } else { if (s->tmiss++ > 2) { mg_error(c, "keepalive"); @@ -971,6 +975,7 @@ void mg_connect_resolved(struct mg_connection *c) { mg_call(c, MG_EV_CONNECT, NULL); } else { send_syn(c); + settmout(c, MIP_TTYPE_SYN); c->is_connecting = 1; } }