This commit is contained in:
Sergio R. Caprile committed 2026-03-31 17:38:04 -03:00
1 parent 1bb85799ce
commit 0d882f1b43
13 files changed
+528 -252

No files matched your search

+15 -8
View File
@@ -551,9 +551,13 @@ static struct mg_connection *getpeer(struct mg_mgr *mgr, struct pkt *pkt,
!(c->loc.is_ip6 ^ (pkt->ip6 != NULL))) // IP or IPv6 to same dest
break;
if (!c->is_udp && pkt->tcp && c->loc.port == pkt->tcp->dport &&
!(c->loc.is_ip6 ^ (pkt->ip6 != NULL)) &&
lsn == (bool) c->is_listening &&
(lsn || c->rem.port == pkt->tcp->sport))
((lsn && c->is_listening && !(c->loc.is_ip6 ^ (pkt->ip6 != NULL))) ||
(!lsn && !c->is_listening && c->rem.port == pkt->tcp->sport &&
((!c->loc.is_ip6 && c->rem.addr.ip4 == pkt->ip->src)
#if MG_ENABLE_IPV6
|| (c->loc.is_ip6 && MG_IP6MATCH(c->rem.addr.ip6, pkt->ip6->src))
#endif
)))) // validate addr for established (not listening) conns
break;
}
return c;
@@ -1497,7 +1501,7 @@ static void backlog_poll(struct mg_mgr *mgr) {
}
// process options (MSS)
static void handle_opt(struct connstate *s, struct tcp *tcp, bool ip6) {
static bool handle_opt(struct connstate *s, struct tcp *tcp, bool ip6) {
uint8_t *opts = (uint8_t *) (tcp + 1);
int len = 4 * ((int) (tcp->off >> 4) - ((int) sizeof(*tcp) / 4));
s->dmss = ip6 ? 1220 : 536; // assume default, RFC-9293 3.7.1
@@ -1505,6 +1509,7 @@ static void handle_opt(struct connstate *s, struct tcp *tcp, bool ip6) {
uint8_t kind = opts[0], optlen = 1;
if (kind != 1) { // No-Operation
if (kind == 0) break; // End of Option List
if (len < 2 || opts[1] == 0) return false; // Malformed options
optlen = opts[1];
if (kind == 2 && optlen == 4) // set received MSS
s->dmss = (uint16_t) (((uint16_t) opts[2] << 8) + opts[3]);
@@ -1513,6 +1518,7 @@ static void handle_opt(struct connstate *s, struct tcp *tcp, bool ip6) {
opts += optlen;
len -= optlen;
}
return true;
}
static void rx_tcp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
@@ -1527,7 +1533,7 @@ static void rx_tcp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
// - check clients (Group 1) and established connections (Group 3)
if (c != NULL && c->is_connecting && pkt->tcp->flags == (TH_SYN | TH_ACK)) {
// client got a server connection accept
handle_opt(s, pkt->tcp, pkt->ip6 != NULL); // process options (MSS)
if (!handle_opt(s, pkt->tcp, pkt->ip6 != NULL)) return; // process options (MSS)
s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq) + 1;
tx_tcp_ctrlresp(ifp, pkt, TH_ACK, pkt->tcp->ack);
c->is_connecting = 0; // Client connected
@@ -1538,8 +1544,9 @@ static void rx_tcp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
} else if (c != NULL && c->is_connecting && pkt->tcp->flags != TH_ACK) {
mg_error(c, "connection refused");
} else if (c != NULL && pkt->tcp->flags & TH_RST) {
// TODO(): validate RST is within window (and optional with proper ACK)
mg_error(c, "peer RST"); // RFC-1122 4.2.2.13
uint32_t seqno = mg_ntohl(pkt->tcp->seq);
if (seqno >= s->ack && seqno < (s->ack + MG_TCPIP_WIN)) // RFC-9293 3.5.3
mg_error(c, "peer RST"); // RFC-1122 4.2.2.13
} else if (c != NULL) {
// process segment
s->tmiss = 0; // Reset missed keep-alive counter
@@ -1561,7 +1568,7 @@ static void rx_tcp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
int key;
uint32_t isn;
if (pkt->tcp->sport != 0) {
handle_opt(&cs, pkt->tcp, pkt->ip6 != NULL); // process options (MSS)
if (!handle_opt(&cs, pkt->tcp, pkt->ip6 != NULL)) return; // process options (MSS)
key = backlog_insert(c, pkt->tcp->sport,
cs.dmss); // backlog options (MSS)
if (key < 0) return; // no room in backlog, discard SYN, client retries