mirror of
https://github.com/cesanta/mongoose.git
synced 2025-08-06 13:37:34 +08:00
make TCP/IP C89-friendly
This commit is contained in:
parent
52ab6bc499
commit
b3ee71acbe
12
.github/workflows/nightly.yml
vendored
12
.github/workflows/nightly.yml
vendored
@ -54,6 +54,18 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
with: { fetch-depth: 2 }
|
||||
- run: if [ "${{ matrix.target }}" == "mip_tap_test" ]; then ./test/setup_ga_network.sh ; fi && sudo apt -y update ; sudo apt -y install libmbedtls-dev libwolfssl-dev && make -C test ${{ matrix.target }} IPV6=0
|
||||
mip89:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: 1 # no parallel runs, to minimize MQTT errors
|
||||
matrix:
|
||||
target: [mip_vc98]
|
||||
name: mip89 ${{ matrix.target }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with: { fetch-depth: 2 }
|
||||
- run: make -C test ${{ matrix.target }}
|
||||
s390:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
|
86
mongoose.c
86
mongoose.c
@ -4327,7 +4327,7 @@ static uint32_t csumup(uint32_t sum, const void *buf, size_t len) {
|
||||
|
||||
static uint16_t csumfin(uint32_t sum) {
|
||||
while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16);
|
||||
return mg_htons(~sum & 0xffff);
|
||||
return mg_htons((uint16_t) (~sum & 0xffff));
|
||||
}
|
||||
|
||||
static uint16_t ipcsum(const void *buf, size_t len) {
|
||||
@ -4414,12 +4414,13 @@ static bool tx_udp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
|
||||
tx_ip(ifp, mac_dst, 17, ip_src, ip_dst, len + sizeof(struct udp));
|
||||
struct udp *udp = (struct udp *) (ip + 1);
|
||||
size_t eth_len;
|
||||
uint32_t cs;
|
||||
// MG_DEBUG(("UDP XX LEN %d %d", (int) len, (int) ifp->tx.len));
|
||||
udp->sport = sport;
|
||||
udp->dport = dport;
|
||||
udp->len = mg_htons((uint16_t) (sizeof(*udp) + len));
|
||||
udp->csum = 0;
|
||||
uint32_t cs = csumup(0, udp, sizeof(*udp));
|
||||
cs = csumup(0, udp, sizeof(*udp));
|
||||
cs = csumup(cs, buf, len);
|
||||
cs = csumup(cs, &ip->src, sizeof(ip->src));
|
||||
cs = csumup(cs, &ip->dst, sizeof(ip->dst));
|
||||
@ -4503,7 +4504,8 @@ static struct mg_connection *getpeer(struct mg_mgr *mgr, struct pkt *pkt,
|
||||
break;
|
||||
if (c->is_udp && pkt->udp && c->loc.port == pkt->udp->dport) break;
|
||||
if (!c->is_udp && pkt->tcp && c->loc.port == pkt->tcp->dport &&
|
||||
lsn == c->is_listening && (lsn || c->rem.port == pkt->tcp->sport))
|
||||
lsn == (bool) c->is_listening &&
|
||||
(lsn || c->rem.port == pkt->tcp->sport))
|
||||
break;
|
||||
}
|
||||
return c;
|
||||
@ -4558,10 +4560,12 @@ static void rx_icmp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
if (pkt->icmp->type == 8 && pkt->ip != NULL && pkt->ip->dst == ifp->ip) {
|
||||
size_t hlen = sizeof(struct eth) + sizeof(struct ip) + sizeof(struct icmp);
|
||||
size_t space = ifp->tx.len - hlen, plen = pkt->pay.len;
|
||||
struct ip *ip;
|
||||
struct icmp *icmp;
|
||||
if (plen > space) plen = space;
|
||||
struct ip *ip = tx_ip(ifp, pkt->eth->src, 1, ifp->ip, pkt->ip->src,
|
||||
sizeof(struct icmp) + plen);
|
||||
struct icmp *icmp = (struct icmp *) (ip + 1);
|
||||
ip = tx_ip(ifp, pkt->eth->src, 1, ifp->ip, pkt->ip->src,
|
||||
sizeof(*icmp) + plen);
|
||||
icmp = (struct icmp *) (ip + 1);
|
||||
memset(icmp, 0, sizeof(*icmp)); // Set csum to 0
|
||||
memcpy(icmp + 1, pkt->pay.buf, plen); // Copy RX payload to TX
|
||||
icmp->csum = ipcsum(icmp, sizeof(*icmp) + plen);
|
||||
@ -4608,13 +4612,13 @@ static void rx_dhcp_client(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
ifp->state = MG_TCPIP_STATE_REQ; // REQUESTING state
|
||||
} else if (msgtype == 5) { // DHCPACK
|
||||
if (ifp->state == MG_TCPIP_STATE_REQ && ip && gw && lease) { // got an IP
|
||||
uint64_t rand;
|
||||
ifp->lease_expire = ifp->now + lease * 1000;
|
||||
MG_INFO(("Lease: %u sec (%lld)", lease, ifp->lease_expire / 1000));
|
||||
// assume DHCP server = router until ARP resolves
|
||||
memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac));
|
||||
ifp->ip = ip, ifp->gw = gw, ifp->mask = mask;
|
||||
ifp->state = MG_TCPIP_STATE_IP; // BOUND state
|
||||
uint64_t rand;
|
||||
mg_random(&rand, sizeof(rand));
|
||||
srand((unsigned int) (rand + mg_millis()));
|
||||
if (ifp->enable_req_dns && dns != 0)
|
||||
@ -4633,9 +4637,9 @@ static void rx_dhcp_client(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_dhcp_server(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
uint8_t op = 0, *p = pkt->dhcp->options,
|
||||
*end = (uint8_t *) &pkt->raw.buf[pkt->raw.len];
|
||||
if (end < (uint8_t *) (pkt->dhcp + 1)) return;
|
||||
// struct dhcp *req = pkt->dhcp;
|
||||
struct dhcp res = {2, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {0}};
|
||||
if (end < (uint8_t *) (pkt->dhcp + 1)) return;
|
||||
res.yiaddr = ifp->ip;
|
||||
((uint8_t *) (&res.yiaddr))[3]++; // Offer our IP + 1
|
||||
while (p + 1 < end && p[0] != 255) { // Parse options
|
||||
@ -4674,9 +4678,9 @@ static void rx_udp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
if (c == NULL) {
|
||||
// No UDP listener on this port. Should send ICMP, but keep silent.
|
||||
} else {
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
c->rem.port = pkt->udp->sport;
|
||||
memcpy(c->rem.ip, &pkt->ip->src, sizeof(uint32_t));
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
memcpy(s->mac, pkt->eth->src, sizeof(s->mac));
|
||||
if (c->recv.len >= MG_MAX_RECV_SIZE) {
|
||||
mg_error(c, "max_recv_buf_size reached");
|
||||
@ -4697,9 +4701,9 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *dst_mac, uint32_t dst_ip,
|
||||
struct ip *ip;
|
||||
struct tcp *tcp;
|
||||
uint16_t opts[4 / 2];
|
||||
if (flags & TH_SYN) { // Send MSS, RFC-9293 3.7.1
|
||||
opts[0] = mg_htons(0x0204); // RFC-9293 3.2
|
||||
opts[1] = mg_htons(ifp->mtu - 40); // RFC-6691
|
||||
if (flags & TH_SYN) { // Send MSS, RFC-9293 3.7.1
|
||||
opts[0] = mg_htons(0x0204); // RFC-9293 3.2
|
||||
opts[1] = mg_htons((uint16_t) (ifp->mtu - 40)); // RFC-6691
|
||||
buf = opts;
|
||||
len = sizeof(opts);
|
||||
}
|
||||
@ -4715,15 +4719,16 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *dst_mac, uint32_t dst_ip,
|
||||
tcp->win = mg_htons(MIP_TCP_WIN);
|
||||
tcp->off = (uint8_t) (sizeof(*tcp) / 4 << 4);
|
||||
if (flags & TH_SYN) tcp->off += (uint8_t) (sizeof(opts) / 4 << 4);
|
||||
|
||||
uint32_t cs = 0;
|
||||
uint16_t n = (uint16_t) (sizeof(*tcp) + len);
|
||||
uint8_t pseudo[] = {0, ip->proto, (uint8_t) (n >> 8), (uint8_t) (n & 255)};
|
||||
cs = csumup(cs, tcp, n);
|
||||
cs = csumup(cs, &ip->src, sizeof(ip->src));
|
||||
cs = csumup(cs, &ip->dst, sizeof(ip->dst));
|
||||
cs = csumup(cs, pseudo, sizeof(pseudo));
|
||||
tcp->csum = csumfin(cs);
|
||||
{
|
||||
uint32_t cs = 0;
|
||||
uint16_t n = (uint16_t) (sizeof(*tcp) + len);
|
||||
uint8_t pseudo[] = {0, ip->proto, (uint8_t) (n >> 8), (uint8_t) (n & 255)};
|
||||
cs = csumup(cs, tcp, n);
|
||||
cs = csumup(cs, &ip->src, sizeof(ip->src));
|
||||
cs = csumup(cs, &ip->dst, sizeof(ip->dst));
|
||||
cs = csumup(cs, pseudo, sizeof(pseudo));
|
||||
tcp->csum = csumfin(cs);
|
||||
}
|
||||
MG_VERBOSE(("TCP %M:%hu -> %M:%hu fl %x len %u", mg_print_ip4, &ip->src,
|
||||
mg_ntohs(tcp->sport), mg_print_ip4, &ip->dst,
|
||||
mg_ntohs(tcp->dport), tcp->flags, len));
|
||||
@ -4743,11 +4748,12 @@ static size_t tx_tcp_pkt(struct mg_tcpip_if *ifp, struct pkt *pkt,
|
||||
static struct mg_connection *accept_conn(struct mg_connection *lsn,
|
||||
struct pkt *pkt) {
|
||||
struct mg_connection *c = mg_alloc_conn(lsn->mgr);
|
||||
struct connstate *s;
|
||||
if (c == NULL) {
|
||||
MG_ERROR(("OOM"));
|
||||
return NULL;
|
||||
}
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
s = (struct connstate *) (c + 1);
|
||||
s->dmss = 536; // assume default, RFC-9293 3.7.1
|
||||
s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq);
|
||||
memcpy(s->mac, pkt->eth->src, sizeof(s->mac));
|
||||
@ -5005,10 +5011,10 @@ static void rx_tcp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_ip(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
uint16_t frag = mg_ntohs(pkt->ip->frag);
|
||||
if (frag & IP_MORE_FRAGS_MSK || frag & IP_FRAG_OFFSET_MSK) {
|
||||
if (pkt->ip->proto == 17) pkt->udp = (struct udp *) (pkt->ip + 1);
|
||||
if (pkt->ip->proto == 6) pkt->tcp = (struct tcp *) (pkt->ip + 1);
|
||||
struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
|
||||
if (c) mg_error(c, "Received fragmented packet");
|
||||
if (pkt->ip->proto == 17) pkt->udp = (struct udp *) (pkt->ip + 1);
|
||||
if (pkt->ip->proto == 6) pkt->tcp = (struct tcp *) (pkt->ip + 1);
|
||||
} else if (pkt->ip->proto == 1) {
|
||||
pkt->icmp = (struct icmp *) (pkt->ip + 1);
|
||||
if (pkt->pay.len < sizeof(*pkt->icmp)) return;
|
||||
@ -5033,11 +5039,12 @@ static void rx_ip(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
rx_udp(ifp, pkt);
|
||||
}
|
||||
} else if (pkt->ip->proto == 6) {
|
||||
uint16_t iplen, off;
|
||||
pkt->tcp = (struct tcp *) (pkt->ip + 1);
|
||||
if (pkt->pay.len < sizeof(*pkt->tcp)) return;
|
||||
mkpay(pkt, pkt->tcp + 1);
|
||||
uint16_t iplen = mg_ntohs(pkt->ip->len);
|
||||
uint16_t off = (uint16_t) (sizeof(*pkt->ip) + ((pkt->tcp->off >> 4) * 4U));
|
||||
iplen = mg_ntohs(pkt->ip->len);
|
||||
off = (uint16_t) (sizeof(*pkt->ip) + ((pkt->tcp->off >> 4) * 4U));
|
||||
if (iplen >= off) pkt->pay.len = (size_t) (iplen - off);
|
||||
MG_VERBOSE(("TCP %M:%hu -> %M:%hu len %u", mg_print_ip4, &pkt->ip->src,
|
||||
mg_ntohs(pkt->tcp->sport), mg_print_ip4, &pkt->ip->dst,
|
||||
@ -5075,8 +5082,9 @@ static void mg_tcpip_rx(struct mg_tcpip_if *ifp, void *buf, size_t len) {
|
||||
memcmp(pkt.eth->dst, broadcast, sizeof(pkt.eth->dst)) != 0)
|
||||
return;
|
||||
if (ifp->enable_crc32_check && len > 4) {
|
||||
uint32_t crc;
|
||||
len -= 4; // TODO(scaprile): check on bigendian
|
||||
uint32_t crc = mg_crc32(0, (const char *) buf, len);
|
||||
crc = mg_crc32(0, (const char *) buf, len);
|
||||
if (memcmp((void *) ((size_t) buf + len), &crc, sizeof(crc))) return;
|
||||
}
|
||||
if (pkt.eth->type == mg_htons(0x806)) {
|
||||
@ -5185,10 +5193,10 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t now) {
|
||||
|
||||
// Process timeouts
|
||||
for (c = ifp->mgr->conns; c != NULL; c = c->next) {
|
||||
if ((c->is_udp && !c->is_arplooking) || c->is_listening || c->is_resolving)
|
||||
continue;
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
uint32_t rem_ip;
|
||||
if ((c->is_udp && !c->is_arplooking) || c->is_listening || c->is_resolving)
|
||||
continue;
|
||||
memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t));
|
||||
if (ifp->now > s->timer) {
|
||||
if (s->ttype == MIP_TTYPE_ARP) {
|
||||
@ -5386,10 +5394,10 @@ void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
|
||||
if (mgr->ifp == NULL || mgr->ifp->driver == NULL) return;
|
||||
mg_tcpip_poll(mgr->ifp, now);
|
||||
for (c = mgr->conns; c != NULL; c = tmp) {
|
||||
tmp = c->next;
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
bool is_tls = c->is_tls && !c->is_resolving && !c->is_arplooking &&
|
||||
!c->is_listening && !c->is_connecting;
|
||||
tmp = c->next;
|
||||
mg_call(c, MG_EV_POLL, &now);
|
||||
MG_VERBOSE(("%lu .. %c%c%c%c%c %lu %lu", c->id, c->is_tls ? 'T' : 't',
|
||||
c->is_connecting ? 'C' : 'c', c->is_tls_hs ? 'H' : 'h',
|
||||
@ -22062,8 +22070,8 @@ struct mg_tcpip_driver mg_tcpip_driver_imxrt = {mg_tcpip_driver_imxrt_init,
|
||||
#endif
|
||||
|
||||
|
||||
enum { // ID1 ID2
|
||||
MG_PHY_KSZ8x = 0x22, // 0022 1561 - KSZ8081RNB
|
||||
enum { // ID1 ID2
|
||||
MG_PHY_KSZ8x = 0x22, // 0022 1561 - KSZ8081RNB
|
||||
MG_PHY_DP83x = 0x2000,
|
||||
MG_PHY_DP83867 = 0xa231, // 2000 a231 - TI DP83867I
|
||||
MG_PHY_DP83825 = 0xa140, // 2000 a140 - TI DP83825I
|
||||
@ -22071,7 +22079,7 @@ enum { // ID1 ID2
|
||||
MG_PHY_LAN87x = 0x7, // 0007 c0fx - LAN8720
|
||||
MG_PHY_RTL8201 = 0x1C, // 001c c816 - RTL8201,
|
||||
MG_PHY_ICS1894x = 0x15,
|
||||
MG_PHY_ICS189432 = 0xf450 // 0015 f450 - ICS1894
|
||||
MG_PHY_ICS189432 = 0xf450 // 0015 f450 - ICS1894
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -22144,11 +22152,13 @@ void mg_phy_init(struct mg_phy *phy, uint8_t phy_addr, uint8_t config) {
|
||||
phy->write_reg(phy_addr, MG_PHY_DP83x_REG_RCSR, MG_BIT(7) | MG_BIT(0));
|
||||
} else if (id1 == MG_PHY_KSZ8x) {
|
||||
// Disable isolation (override hw, it doesn't make sense at this point)
|
||||
phy->write_reg( // #2848, some NXP boards set ISO, even though
|
||||
phy_addr, MG_PHY_REG_BCR, // docs say they don't
|
||||
phy->read_reg(phy_addr, MG_PHY_REG_BCR) & (uint16_t) ~MG_BIT(10));
|
||||
phy->write_reg(phy_addr, MG_PHY_KSZ8x_REG_PC2R, // now do clock stuff
|
||||
MG_BIT(15) | MG_BIT(8) | MG_BIT(7));
|
||||
// - #2848, some NXP boards set ISO, even though docs say they don't
|
||||
phy->write_reg(phy_addr, MG_PHY_REG_BCR,
|
||||
(uint16_t) (phy->read_reg(phy_addr, MG_PHY_REG_BCR) &
|
||||
(uint16_t) ~MG_BIT(10)));
|
||||
// now do clock stuff
|
||||
phy->write_reg(phy_addr, MG_PHY_KSZ8x_REG_PC2R,
|
||||
(uint16_t) (MG_BIT(15) | MG_BIT(8) | MG_BIT(7)));
|
||||
} else if (id1 == MG_PHY_LAN87x) {
|
||||
// nothing to do
|
||||
} else if (id1 == MG_PHY_RTL8201) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "phy.h"
|
||||
|
||||
enum { // ID1 ID2
|
||||
MG_PHY_KSZ8x = 0x22, // 0022 1561 - KSZ8081RNB
|
||||
enum { // ID1 ID2
|
||||
MG_PHY_KSZ8x = 0x22, // 0022 1561 - KSZ8081RNB
|
||||
MG_PHY_DP83x = 0x2000,
|
||||
MG_PHY_DP83867 = 0xa231, // 2000 a231 - TI DP83867I
|
||||
MG_PHY_DP83825 = 0xa140, // 2000 a140 - TI DP83825I
|
||||
@ -9,7 +9,7 @@ enum { // ID1 ID2
|
||||
MG_PHY_LAN87x = 0x7, // 0007 c0fx - LAN8720
|
||||
MG_PHY_RTL8201 = 0x1C, // 001c c816 - RTL8201,
|
||||
MG_PHY_ICS1894x = 0x15,
|
||||
MG_PHY_ICS189432 = 0xf450 // 0015 f450 - ICS1894
|
||||
MG_PHY_ICS189432 = 0xf450 // 0015 f450 - ICS1894
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -82,11 +82,13 @@ void mg_phy_init(struct mg_phy *phy, uint8_t phy_addr, uint8_t config) {
|
||||
phy->write_reg(phy_addr, MG_PHY_DP83x_REG_RCSR, MG_BIT(7) | MG_BIT(0));
|
||||
} else if (id1 == MG_PHY_KSZ8x) {
|
||||
// Disable isolation (override hw, it doesn't make sense at this point)
|
||||
phy->write_reg( // #2848, some NXP boards set ISO, even though
|
||||
phy_addr, MG_PHY_REG_BCR, // docs say they don't
|
||||
phy->read_reg(phy_addr, MG_PHY_REG_BCR) & (uint16_t) ~MG_BIT(10));
|
||||
phy->write_reg(phy_addr, MG_PHY_KSZ8x_REG_PC2R, // now do clock stuff
|
||||
MG_BIT(15) | MG_BIT(8) | MG_BIT(7));
|
||||
// - #2848, some NXP boards set ISO, even though docs say they don't
|
||||
phy->write_reg(phy_addr, MG_PHY_REG_BCR,
|
||||
(uint16_t) (phy->read_reg(phy_addr, MG_PHY_REG_BCR) &
|
||||
(uint16_t) ~MG_BIT(10)));
|
||||
// now do clock stuff
|
||||
phy->write_reg(phy_addr, MG_PHY_KSZ8x_REG_PC2R,
|
||||
(uint16_t) (MG_BIT(15) | MG_BIT(8) | MG_BIT(7)));
|
||||
} else if (id1 == MG_PHY_LAN87x) {
|
||||
// nothing to do
|
||||
} else if (id1 == MG_PHY_RTL8201) {
|
||||
|
@ -161,7 +161,7 @@ static uint32_t csumup(uint32_t sum, const void *buf, size_t len) {
|
||||
|
||||
static uint16_t csumfin(uint32_t sum) {
|
||||
while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16);
|
||||
return mg_htons(~sum & 0xffff);
|
||||
return mg_htons((uint16_t) ((uint16_t) ~sum & 0xffff));
|
||||
}
|
||||
|
||||
static uint16_t ipcsum(const void *buf, size_t len) {
|
||||
@ -248,12 +248,13 @@ static bool tx_udp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
|
||||
tx_ip(ifp, mac_dst, 17, ip_src, ip_dst, len + sizeof(struct udp));
|
||||
struct udp *udp = (struct udp *) (ip + 1);
|
||||
size_t eth_len;
|
||||
uint32_t cs;
|
||||
// MG_DEBUG(("UDP XX LEN %d %d", (int) len, (int) ifp->tx.len));
|
||||
udp->sport = sport;
|
||||
udp->dport = dport;
|
||||
udp->len = mg_htons((uint16_t) (sizeof(*udp) + len));
|
||||
udp->csum = 0;
|
||||
uint32_t cs = csumup(0, udp, sizeof(*udp));
|
||||
cs = csumup(0, udp, sizeof(*udp));
|
||||
cs = csumup(cs, buf, len);
|
||||
cs = csumup(cs, &ip->src, sizeof(ip->src));
|
||||
cs = csumup(cs, &ip->dst, sizeof(ip->dst));
|
||||
@ -337,7 +338,8 @@ static struct mg_connection *getpeer(struct mg_mgr *mgr, struct pkt *pkt,
|
||||
break;
|
||||
if (c->is_udp && pkt->udp && c->loc.port == pkt->udp->dport) break;
|
||||
if (!c->is_udp && pkt->tcp && c->loc.port == pkt->tcp->dport &&
|
||||
lsn == c->is_listening && (lsn || c->rem.port == pkt->tcp->sport))
|
||||
lsn == (bool) c->is_listening &&
|
||||
(lsn || c->rem.port == pkt->tcp->sport))
|
||||
break;
|
||||
}
|
||||
return c;
|
||||
@ -392,10 +394,12 @@ static void rx_icmp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
if (pkt->icmp->type == 8 && pkt->ip != NULL && pkt->ip->dst == ifp->ip) {
|
||||
size_t hlen = sizeof(struct eth) + sizeof(struct ip) + sizeof(struct icmp);
|
||||
size_t space = ifp->tx.len - hlen, plen = pkt->pay.len;
|
||||
struct ip *ip;
|
||||
struct icmp *icmp;
|
||||
if (plen > space) plen = space;
|
||||
struct ip *ip = tx_ip(ifp, pkt->eth->src, 1, ifp->ip, pkt->ip->src,
|
||||
sizeof(struct icmp) + plen);
|
||||
struct icmp *icmp = (struct icmp *) (ip + 1);
|
||||
ip = tx_ip(ifp, pkt->eth->src, 1, ifp->ip, pkt->ip->src,
|
||||
sizeof(*icmp) + plen);
|
||||
icmp = (struct icmp *) (ip + 1);
|
||||
memset(icmp, 0, sizeof(*icmp)); // Set csum to 0
|
||||
memcpy(icmp + 1, pkt->pay.buf, plen); // Copy RX payload to TX
|
||||
icmp->csum = ipcsum(icmp, sizeof(*icmp) + plen);
|
||||
@ -442,13 +446,13 @@ static void rx_dhcp_client(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
ifp->state = MG_TCPIP_STATE_REQ; // REQUESTING state
|
||||
} else if (msgtype == 5) { // DHCPACK
|
||||
if (ifp->state == MG_TCPIP_STATE_REQ && ip && gw && lease) { // got an IP
|
||||
uint64_t rand;
|
||||
ifp->lease_expire = ifp->now + lease * 1000;
|
||||
MG_INFO(("Lease: %u sec (%lld)", lease, ifp->lease_expire / 1000));
|
||||
// assume DHCP server = router until ARP resolves
|
||||
memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac));
|
||||
ifp->ip = ip, ifp->gw = gw, ifp->mask = mask;
|
||||
ifp->state = MG_TCPIP_STATE_IP; // BOUND state
|
||||
uint64_t rand;
|
||||
mg_random(&rand, sizeof(rand));
|
||||
srand((unsigned int) (rand + mg_millis()));
|
||||
if (ifp->enable_req_dns && dns != 0)
|
||||
@ -467,9 +471,9 @@ static void rx_dhcp_client(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_dhcp_server(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
uint8_t op = 0, *p = pkt->dhcp->options,
|
||||
*end = (uint8_t *) &pkt->raw.buf[pkt->raw.len];
|
||||
if (end < (uint8_t *) (pkt->dhcp + 1)) return;
|
||||
// struct dhcp *req = pkt->dhcp;
|
||||
struct dhcp res = {2, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {0}};
|
||||
if (end < (uint8_t *) (pkt->dhcp + 1)) return;
|
||||
res.yiaddr = ifp->ip;
|
||||
((uint8_t *) (&res.yiaddr))[3]++; // Offer our IP + 1
|
||||
while (p + 1 < end && p[0] != 255) { // Parse options
|
||||
@ -508,9 +512,9 @@ static void rx_udp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
if (c == NULL) {
|
||||
// No UDP listener on this port. Should send ICMP, but keep silent.
|
||||
} else {
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
c->rem.port = pkt->udp->sport;
|
||||
memcpy(c->rem.ip, &pkt->ip->src, sizeof(uint32_t));
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
memcpy(s->mac, pkt->eth->src, sizeof(s->mac));
|
||||
if (c->recv.len >= MG_MAX_RECV_SIZE) {
|
||||
mg_error(c, "max_recv_buf_size reached");
|
||||
@ -531,9 +535,9 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *dst_mac, uint32_t dst_ip,
|
||||
struct ip *ip;
|
||||
struct tcp *tcp;
|
||||
uint16_t opts[4 / 2];
|
||||
if (flags & TH_SYN) { // Send MSS, RFC-9293 3.7.1
|
||||
opts[0] = mg_htons(0x0204); // RFC-9293 3.2
|
||||
opts[1] = mg_htons(ifp->mtu - 40); // RFC-6691
|
||||
if (flags & TH_SYN) { // Send MSS, RFC-9293 3.7.1
|
||||
opts[0] = mg_htons(0x0204); // RFC-9293 3.2
|
||||
opts[1] = mg_htons((uint16_t) (ifp->mtu - 40)); // RFC-6691
|
||||
buf = opts;
|
||||
len = sizeof(opts);
|
||||
}
|
||||
@ -549,15 +553,16 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *dst_mac, uint32_t dst_ip,
|
||||
tcp->win = mg_htons(MIP_TCP_WIN);
|
||||
tcp->off = (uint8_t) (sizeof(*tcp) / 4 << 4);
|
||||
if (flags & TH_SYN) tcp->off += (uint8_t) (sizeof(opts) / 4 << 4);
|
||||
|
||||
uint32_t cs = 0;
|
||||
uint16_t n = (uint16_t) (sizeof(*tcp) + len);
|
||||
uint8_t pseudo[] = {0, ip->proto, (uint8_t) (n >> 8), (uint8_t) (n & 255)};
|
||||
cs = csumup(cs, tcp, n);
|
||||
cs = csumup(cs, &ip->src, sizeof(ip->src));
|
||||
cs = csumup(cs, &ip->dst, sizeof(ip->dst));
|
||||
cs = csumup(cs, pseudo, sizeof(pseudo));
|
||||
tcp->csum = csumfin(cs);
|
||||
{
|
||||
uint32_t cs = 0;
|
||||
uint16_t n = (uint16_t) (sizeof(*tcp) + len);
|
||||
uint8_t pseudo[] = {0, ip->proto, (uint8_t) (n >> 8), (uint8_t) (n & 255)};
|
||||
cs = csumup(cs, tcp, n);
|
||||
cs = csumup(cs, &ip->src, sizeof(ip->src));
|
||||
cs = csumup(cs, &ip->dst, sizeof(ip->dst));
|
||||
cs = csumup(cs, pseudo, sizeof(pseudo));
|
||||
tcp->csum = csumfin(cs);
|
||||
}
|
||||
MG_VERBOSE(("TCP %M:%hu -> %M:%hu fl %x len %u", mg_print_ip4, &ip->src,
|
||||
mg_ntohs(tcp->sport), mg_print_ip4, &ip->dst,
|
||||
mg_ntohs(tcp->dport), tcp->flags, len));
|
||||
@ -577,11 +582,12 @@ static size_t tx_tcp_pkt(struct mg_tcpip_if *ifp, struct pkt *pkt,
|
||||
static struct mg_connection *accept_conn(struct mg_connection *lsn,
|
||||
struct pkt *pkt) {
|
||||
struct mg_connection *c = mg_alloc_conn(lsn->mgr);
|
||||
struct connstate *s;
|
||||
if (c == NULL) {
|
||||
MG_ERROR(("OOM"));
|
||||
return NULL;
|
||||
}
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
s = (struct connstate *) (c + 1);
|
||||
s->dmss = 536; // assume default, RFC-9293 3.7.1
|
||||
s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq);
|
||||
memcpy(s->mac, pkt->eth->src, sizeof(s->mac));
|
||||
@ -839,10 +845,10 @@ static void rx_tcp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_ip(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
uint16_t frag = mg_ntohs(pkt->ip->frag);
|
||||
if (frag & IP_MORE_FRAGS_MSK || frag & IP_FRAG_OFFSET_MSK) {
|
||||
if (pkt->ip->proto == 17) pkt->udp = (struct udp *) (pkt->ip + 1);
|
||||
if (pkt->ip->proto == 6) pkt->tcp = (struct tcp *) (pkt->ip + 1);
|
||||
struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
|
||||
if (c) mg_error(c, "Received fragmented packet");
|
||||
if (pkt->ip->proto == 17) pkt->udp = (struct udp *) (pkt->ip + 1);
|
||||
if (pkt->ip->proto == 6) pkt->tcp = (struct tcp *) (pkt->ip + 1);
|
||||
} else if (pkt->ip->proto == 1) {
|
||||
pkt->icmp = (struct icmp *) (pkt->ip + 1);
|
||||
if (pkt->pay.len < sizeof(*pkt->icmp)) return;
|
||||
@ -867,11 +873,12 @@ static void rx_ip(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
rx_udp(ifp, pkt);
|
||||
}
|
||||
} else if (pkt->ip->proto == 6) {
|
||||
uint16_t iplen, off;
|
||||
pkt->tcp = (struct tcp *) (pkt->ip + 1);
|
||||
if (pkt->pay.len < sizeof(*pkt->tcp)) return;
|
||||
mkpay(pkt, pkt->tcp + 1);
|
||||
uint16_t iplen = mg_ntohs(pkt->ip->len);
|
||||
uint16_t off = (uint16_t) (sizeof(*pkt->ip) + ((pkt->tcp->off >> 4) * 4U));
|
||||
iplen = mg_ntohs(pkt->ip->len);
|
||||
off = (uint16_t) (sizeof(*pkt->ip) + ((pkt->tcp->off >> 4) * 4U));
|
||||
if (iplen >= off) pkt->pay.len = (size_t) (iplen - off);
|
||||
MG_VERBOSE(("TCP %M:%hu -> %M:%hu len %u", mg_print_ip4, &pkt->ip->src,
|
||||
mg_ntohs(pkt->tcp->sport), mg_print_ip4, &pkt->ip->dst,
|
||||
@ -909,8 +916,9 @@ static void mg_tcpip_rx(struct mg_tcpip_if *ifp, void *buf, size_t len) {
|
||||
memcmp(pkt.eth->dst, broadcast, sizeof(pkt.eth->dst)) != 0)
|
||||
return;
|
||||
if (ifp->enable_crc32_check && len > 4) {
|
||||
uint32_t crc;
|
||||
len -= 4; // TODO(scaprile): check on bigendian
|
||||
uint32_t crc = mg_crc32(0, (const char *) buf, len);
|
||||
crc = mg_crc32(0, (const char *) buf, len);
|
||||
if (memcmp((void *) ((size_t) buf + len), &crc, sizeof(crc))) return;
|
||||
}
|
||||
if (pkt.eth->type == mg_htons(0x806)) {
|
||||
@ -1019,10 +1027,10 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t now) {
|
||||
|
||||
// Process timeouts
|
||||
for (c = ifp->mgr->conns; c != NULL; c = c->next) {
|
||||
if ((c->is_udp && !c->is_arplooking) || c->is_listening || c->is_resolving)
|
||||
continue;
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
uint32_t rem_ip;
|
||||
if ((c->is_udp && !c->is_arplooking) || c->is_listening || c->is_resolving)
|
||||
continue;
|
||||
memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t));
|
||||
if (ifp->now > s->timer) {
|
||||
if (s->ttype == MIP_TTYPE_ARP) {
|
||||
@ -1220,10 +1228,10 @@ void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
|
||||
if (mgr->ifp == NULL || mgr->ifp->driver == NULL) return;
|
||||
mg_tcpip_poll(mgr->ifp, now);
|
||||
for (c = mgr->conns; c != NULL; c = tmp) {
|
||||
tmp = c->next;
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
bool is_tls = c->is_tls && !c->is_resolving && !c->is_arplooking &&
|
||||
!c->is_listening && !c->is_connecting;
|
||||
tmp = c->next;
|
||||
mg_call(c, MG_EV_POLL, &now);
|
||||
MG_VERBOSE(("%lu .. %c%c%c%c%c %lu %lu", c->id, c->is_tls ? 'T' : 't',
|
||||
c->is_connecting ? 'C' : 'c', c->is_tls_hs ? 'H' : 'h',
|
||||
|
@ -91,6 +91,10 @@ mip_tap_test: mip_tap_test.c mongoose.c mongoose.h packed_fs.c Makefile tls_mult
|
||||
$(CC) mip_tap_test.c packed_fs.c $(CFLAGS) $(LDFLAGS) -o $@
|
||||
ASAN_OPTIONS=$(ASAN_OPTIONS) $(RUN) ./$@
|
||||
|
||||
mip_vc98: mip_test.c mongoose.c mongoose.h packed_fs.c Makefile
|
||||
$(DOCKER) mdashnet/vc98 wine cl mip_test.c packed_fs.c $(VCFLAGS) $(DEFS) $(TFLAGS) /Fe$@.exe
|
||||
$(DOCKER) mdashnet/vc98 wine $@.exe
|
||||
|
||||
packed_fs.c: Makefile data/ssi.h fuzz.c data/a.txt data/ca.pem certs/ca.crt certs/server.crt certs/server.key
|
||||
$(CC) $(CFLAGS) pack.c -o pack
|
||||
$(RUN) ./pack Makefile data/ssi.h fuzz.c data/a.txt data/range.txt data/ca.pem certs/ca.crt certs/server.crt certs/server.key certs/client.key certs/client.crt > $@
|
||||
|
@ -74,9 +74,9 @@ static void frag_send_fn(struct mg_connection *c, int ev, void *ev_data) {
|
||||
|
||||
static void test_poll(void) {
|
||||
int count = 0, i;
|
||||
struct mg_tcpip_if mif;
|
||||
struct mg_mgr mgr;
|
||||
mg_mgr_init(&mgr);
|
||||
struct mg_tcpip_if mif;
|
||||
memset(&mif, 0, sizeof(mif));
|
||||
mif.driver = &mg_tcpip_driver_mock;
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
@ -295,6 +295,7 @@ static void test_frag_send_path(void) {
|
||||
struct mg_mgr mgr;
|
||||
struct mg_tcpip_driver driver;
|
||||
struct mg_tcpip_if mif;
|
||||
unsigned int i;
|
||||
|
||||
mg_mgr_init(&mgr);
|
||||
memset(&mif, 0, sizeof(mif));
|
||||
@ -307,7 +308,7 @@ static void test_frag_send_path(void) {
|
||||
mif.mtu = 500; // force ad hoc small MTU to fragment IP
|
||||
mg_http_listen(&mgr, "http://0.0.0.0:0", frag_send_fn, NULL);
|
||||
mgr.conns->pfn = NULL;
|
||||
for (int i = 0; i < 10; i++) mg_mgr_poll(&mgr, 0);
|
||||
for (i = 0; i < 10; i++) mg_mgr_poll(&mgr, 0);
|
||||
ASSERT(s_seg_sent == 3);
|
||||
s_driver_data.len = 0;
|
||||
mg_mgr_free(&mgr);
|
||||
|
Loading…
Reference in New Issue
Block a user