diff --git a/mongoose.c b/mongoose.c index f0bd66ea..a4a564a5 100644 --- a/mongoose.c +++ b/mongoose.c @@ -4865,13 +4865,14 @@ static void read_conn(struct mg_connection *c, struct pkt *pkt) { tx_tcp(c->mgr->ifp, s->mac, rem_ip, flags, c->loc.port, c->rem.port, mg_htonl(s->seq), mg_htonl(s->ack), "", 0); if (pkt->pay.len == 0) return; // if no data, we're done - } else if (pkt->pay.len == 0) { // this is an ACK + } else if (pkt->pay.len <= 1 && mg_ntohl(pkt->tcp->seq) == s->ack - 1) { + // Keep-Alive (RFC-9293 3.8.4, allow erroneous implementations) + MG_VERBOSE(("%lu keepalive ACK", c->id)); + tx_tcp(c->mgr->ifp, s->mac, rem_ip, TH_ACK, c->loc.port, c->rem.port, + mg_htonl(s->seq), mg_htonl(s->ack), NULL, 0); + return; // no data to process + } else if (pkt->pay.len == 0) { // this is an ACK if (s->fin_rcvd && s->ttype == MIP_TTYPE_FIN) s->twclosure = true; - if (mg_ntohl(pkt->tcp->seq) == s->ack - 1) { // this is a keepalive probe - MG_VERBOSE(("%lu keepalive ACK", c->id)); - tx_tcp(c->mgr->ifp, s->mac, rem_ip, TH_ACK, c->loc.port, c->rem.port, - mg_htonl(s->seq), mg_htonl(s->ack), NULL, 0); - } return; // no data to process } else if (seq != s->ack) { uint32_t ack = (uint32_t) (mg_htonl(pkt->tcp->seq) + pkt->pay.len); diff --git a/src/net_builtin.c b/src/net_builtin.c index 3780292a..37b64b51 100644 --- a/src/net_builtin.c +++ b/src/net_builtin.c @@ -701,13 +701,14 @@ static void read_conn(struct mg_connection *c, struct pkt *pkt) { tx_tcp(c->mgr->ifp, s->mac, rem_ip, flags, c->loc.port, c->rem.port, mg_htonl(s->seq), mg_htonl(s->ack), "", 0); if (pkt->pay.len == 0) return; // if no data, we're done - } else if (pkt->pay.len == 0) { // this is an ACK + } else if (pkt->pay.len <= 1 && mg_ntohl(pkt->tcp->seq) == s->ack - 1) { + // Keep-Alive (RFC-9293 3.8.4, allow erroneous implementations) + MG_VERBOSE(("%lu keepalive ACK", c->id)); + tx_tcp(c->mgr->ifp, s->mac, rem_ip, TH_ACK, c->loc.port, c->rem.port, + mg_htonl(s->seq), mg_htonl(s->ack), NULL, 0); + return; // no data to process + } else if (pkt->pay.len == 0) { // this is an ACK if (s->fin_rcvd && s->ttype == MIP_TTYPE_FIN) s->twclosure = true; - if (mg_ntohl(pkt->tcp->seq) == s->ack - 1) { // this is a keepalive probe - MG_VERBOSE(("%lu keepalive ACK", c->id)); - tx_tcp(c->mgr->ifp, s->mac, rem_ip, TH_ACK, c->loc.port, c->rem.port, - mg_htonl(s->seq), mg_htonl(s->ack), NULL, 0); - } return; // no data to process } else if (seq != s->ack) { uint32_t ack = (uint32_t) (mg_htonl(pkt->tcp->seq) + pkt->pay.len);