diff --git a/mongoose.c b/mongoose.c index 1ef80b22..96852cff 100644 --- a/mongoose.c +++ b/mongoose.c @@ -257,12 +257,12 @@ bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *dm) { if (rr.alen == 4 && rr.atype == 1 && rr.aclass == 1) { dm->addr.is_ip6 = false; - memcpy(&dm->addr.ip, &buf[ofs - 4], 4); + memcpy(&dm->addr.addr.ip, &buf[ofs - 4], 4); dm->resolved = true; break; // Return success } else if (rr.alen == 16 && rr.atype == 28 && rr.aclass == 1) { dm->addr.is_ip6 = true; - memcpy(&dm->addr.ip, &buf[ofs - 16], 16); + memcpy(&dm->addr.addr.ip, &buf[ofs - 16], 16); dm->resolved = true; break; // Return success } @@ -787,7 +787,8 @@ static int xisinf(double x) { union { double f; uint64_t u; - } ieee754 = {x}; + } ieee754; + ieee754.f = x; return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 && ((unsigned) ieee754.u == 0); } @@ -796,7 +797,8 @@ static int xisnan(double x) { union { double f; uint64_t u; - } ieee754 = {x}; + } ieee754; + ieee754.f = x; return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) + ((unsigned) ieee754.u != 0) > 0x7ff00000; @@ -864,7 +866,7 @@ static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width, bool tz) { } while (tz && n > 0 && buf[s + n - 1] == '0') n--; // Trim trailing zeroes - if (tz && n > 0 && buf[s + n - 1] == '.') n--; // Trim trailing dot + if (tz && n > 0 && buf[s + n - 1] == '.') n--; // Trim trailing dot n += s; if (n >= (int) sizeof(buf)) n = (int) sizeof(buf) - 1; buf[n] = '\0'; @@ -894,7 +896,7 @@ static size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex) { } static size_t scpy(void (*out)(char, void *), void *ptr, char *buf, - size_t len) { + size_t len) { size_t i = 0; while (i < len && buf[i] != '\0') out(buf[i++], ptr); return i; @@ -1088,7 +1090,8 @@ static void mg_fs_ls_fn(const char *filename, void *param) { } bool mg_fs_ls(struct mg_fs *fs, const char *path, char *buf, size_t len) { - struct mg_str s = {buf, len}; + struct mg_str s; + s.buf = buf, s.len = len; fs->ls(path, mg_fs_ls_fn, &s); return buf[0] != '\0'; } @@ -3749,7 +3752,8 @@ void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts) { char client_id[21]; struct mg_str cid = opts->client_id; size_t total_len = 7 + 1 + 2 + 2; - uint8_t hdr[8] = {0, 4, 'M', 'Q', 'T', 'T', opts->version, 0}; + uint8_t hdr[8] = {0, 4, 'M', 'Q', 'T', 'T', 0, 0}; + hdr[6] = opts->version; if (cid.len == 0) { mg_random_str(client_id, sizeof(client_id) - 1); @@ -4107,14 +4111,14 @@ size_t mg_printf(struct mg_connection *c, const char *fmt, ...) { static bool mg_atonl(struct mg_str str, struct mg_addr *addr) { uint32_t localhost = mg_htonl(0x7f000001); if (mg_strcasecmp(str, mg_str("localhost")) != 0) return false; - memcpy(addr->ip, &localhost, sizeof(uint32_t)); + memcpy(addr->addr.ip, &localhost, sizeof(uint32_t)); addr->is_ip6 = false; return true; } static bool mg_atone(struct mg_str str, struct mg_addr *addr) { if (str.len > 0) return false; - memset(addr->ip, 0, sizeof(addr->ip)); + memset(addr->addr.ip, 0, sizeof(addr->addr.ip)); addr->is_ip6 = false; return true; } @@ -4135,7 +4139,7 @@ static bool mg_aton4(struct mg_str str, struct mg_addr *addr) { } } if (num_dots != 3 || str.buf[i - 1] == '.') return false; - memcpy(&addr->ip, data, sizeof(data)); + memcpy(&addr->addr.ip, data, sizeof(data)); addr->is_ip6 = false; return true; } @@ -4150,10 +4154,10 @@ static bool mg_v4mapped(struct mg_str str, struct mg_addr *addr) { } // struct mg_str s = mg_str_n(&str.buf[7], str.len - 7); if (!mg_aton4(mg_str_n(&str.buf[7], str.len - 7), addr)) return false; - memcpy(&ipv4, addr->ip, sizeof(ipv4)); - memset(addr->ip, 0, sizeof(addr->ip)); - addr->ip[10] = addr->ip[11] = 255; - memcpy(&addr->ip[12], &ipv4, 4); + memcpy(&ipv4, addr->addr.ip, sizeof(ipv4)); + memset(addr->addr.ip, 0, sizeof(addr->addr.ip)); + addr->addr.ip[10] = addr->addr.ip[11] = 255; + memcpy(&addr->addr.ip[12], &ipv4, 4); addr->is_ip6 = true; return true; } @@ -4171,8 +4175,8 @@ static bool mg_aton6(struct mg_str str, struct mg_addr *addr) { if (i > j + 3) return false; // MG_DEBUG(("%lu %lu [%.*s]", i, j, (int) (i - j + 1), &str.buf[j])); mg_str_to_num(mg_str_n(&str.buf[j], i - j + 1), 16, &val, sizeof(val)); - addr->ip[n] = (uint8_t) ((val >> 8) & 255); - addr->ip[n + 1] = (uint8_t) (val & 255); + addr->addr.ip[n] = (uint8_t) ((val >> 8) & 255); + addr->addr.ip[n + 1] = (uint8_t) (val & 255); } else if (str.buf[i] == ':') { j = i + 1; if (i > 0 && str.buf[i - 1] == ':') { @@ -4182,8 +4186,8 @@ static bool mg_aton6(struct mg_str str, struct mg_addr *addr) { n += 2; } if (n > 14) return false; - addr->ip[n] = addr->ip[n + 1] = 0; // For trailing :: - } else if (str.buf[i] == '%') { // Scope ID, last in string + addr->addr.ip[n] = addr->addr.ip[n + 1] = 0; // For trailing :: + } else if (str.buf[i] == '%') { // Scope ID, last in string if (mg_str_to_num(mg_str_n(&str.buf[i + 1], str.len - i - 1), 10, &addr->scope_id, sizeof(uint8_t))) { addr->is_ip6 = true; @@ -4197,8 +4201,8 @@ static bool mg_aton6(struct mg_str str, struct mg_addr *addr) { } if (n < 14 && dc == 42) return false; if (n < 14) { - memmove(&addr->ip[dc + (14 - n)], &addr->ip[dc], n - dc + 2); - memset(&addr->ip[dc], 0, 14 - n); + memmove(&addr->addr.ip[dc + (14 - n)], &addr->addr.ip[dc], n - dc + 2); + memset(&addr->addr.ip[dc], 0, 14 - n); } addr->is_ip6 = true; @@ -4422,7 +4426,11 @@ struct connstate { bool twclosure; // 3-way closure done }; +#if defined(__DCC__) +#pragma pack(1) +#else #pragma pack(push, 1) +#endif struct lcp { uint8_t addr, ctrl, proto[2], code, id, len[2]; @@ -4541,7 +4549,11 @@ struct dhcp6 { uint8_t options[30 + sizeof(((struct mg_tcpip_if *) 0)->dhcp_name)]; }; +#if defined(__DCC__) +#pragma pack(0) +#else #pragma pack(pop) +#endif // pkt is 8-bit aligned, pointers to headers hint compilers to generate // byte-copy code for micros with alignment constraints @@ -4744,14 +4756,14 @@ static bool tx_udp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, #if MG_ENABLE_IPV6 struct ip6 *ip6 = NULL; if (ip_dst->is_ip6) { - ip6 = tx_ip6(ifp, mac_dst, 17, ip_src->ip6, ip_dst->ip6, + ip6 = tx_ip6(ifp, mac_dst, 17, ip_src->addr.ip6, ip_dst->addr.ip6, len + sizeof(struct udp)); udp = (struct udp *) (ip6 + 1); eth_len = sizeof(struct eth) + sizeof(*ip6) + sizeof(*udp) + len; } else #endif { - ip = tx_ip(ifp, mac_dst, 17, ip_src->ip4, ip_dst->ip4, + ip = tx_ip(ifp, mac_dst, 17, ip_src->addr.ip4, ip_dst->addr.ip4, len + sizeof(struct udp)); udp = (struct udp *) (ip + 1); eth_len = sizeof(struct eth) + sizeof(*ip) + sizeof(*udp) + len; @@ -4783,10 +4795,10 @@ static bool tx_udp4(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src, const void *buf, size_t len) { struct mg_addr ips, ipd; memset(&ips, 0, sizeof(ips)); - ips.ip4 = ip_src; + ips.addr.ip4 = ip_src; ips.port = sport; memset(&ipd, 0, sizeof(ipd)); - ipd.ip4 = ip_dst; + ipd.addr.ip4 = ip_dst; ipd.port = dport; return tx_udp(ifp, mac_dst, &ips, &ipd, buf, len); } @@ -4858,11 +4870,11 @@ static struct mg_connection *getpeer(struct mg_mgr *mgr, struct pkt *pkt, bool lsn) { struct mg_connection *c = NULL; for (c = mgr->conns; c != NULL; c = c->next) { - if (c->is_arplooking && pkt->arp && pkt->arp->spa == c->rem.ip4) break; + if (c->is_arplooking && pkt->arp && pkt->arp->spa == c->rem.addr.ip4) break; #if MG_ENABLE_IPV6 if (c->is_arplooking && pkt->icmp6 && pkt->icmp6->type == 136) { struct ndp_na *na = (struct ndp_na *) (pkt->icmp6 + 1); - if (MG_IP6MATCH(na->addr, c->rem.ip6)) break; + if (MG_IP6MATCH(na->addr, c->rem.addr.ip6)) break; } #endif if (c->is_udp && pkt->udp && c->loc.port == pkt->udp->dport && @@ -4914,8 +4926,8 @@ static void rx_arp(struct mg_tcpip_if *ifp, struct pkt *pkt) { if (c != NULL && c->is_arplooking) { struct connstate *s = (struct connstate *) (c + 1); memcpy(s->mac, pkt->arp->sha, sizeof(s->mac)); - MG_DEBUG(("%lu ARP resolved %M -> %M", c->id, mg_print_ip4, c->rem.ip, - mg_print_mac, s->mac)); + MG_DEBUG(("%lu ARP resolved %M -> %M", c->id, mg_print_ip4, + c->rem.addr.ip, mg_print_mac, s->mac)); c->is_arplooking = 0; mac_resolved(c); } @@ -4930,7 +4942,7 @@ static void rx_icmp(struct mg_tcpip_if *ifp, struct pkt *pkt) { struct ip *ip; struct icmp *icmp; struct mg_addr ips; - ips.ip4 = pkt->ip->src; + ips.addr.ip4 = pkt->ip->src; ips.is_ip6 = false; if (get_return_mac(ifp, &ips, false, pkt) == NULL) return; // safety net for lousy networks @@ -5028,13 +5040,14 @@ static void rx_dhcp_server(struct mg_tcpip_if *ifp, struct pkt *pkt) { if (op == 1 || op == 3) { // DHCP Discover or DHCP Request uint8_t msg = op == 1 ? 2 : 5; // Message type: DHCP OFFER or DHCP ACK uint8_t opts[] = { - 53, 1, msg, // Message type + 53, 1, 0, // Message type 1, 4, 0, 0, 0, 0, // Subnet mask 54, 4, 0, 0, 0, 0, // Server ID 12, 3, 'm', 'i', 'p', // Host name: "mip" 51, 4, 255, 255, 255, 255, // Lease time 255 // End of options }; + opts[2] = msg; memcpy(&res.hwaddr, pkt->dhcp->hwaddr, 6); memcpy(opts + 5, &ifp->mask, sizeof(ifp->mask)); memcpy(opts + 11, &ifp->ip, sizeof(ifp->ip)); @@ -5130,8 +5143,8 @@ static void rx_ndp_na(struct mg_tcpip_if *ifp, struct pkt *pkt) { if (c != NULL && c->is_arplooking) { struct connstate *s = (struct connstate *) (c + 1); memcpy(s->mac, opts, sizeof(s->mac)); - MG_DEBUG(("%lu NDP resolved %M -> %M", c->id, mg_print_ip6, c->rem.ip, - mg_print_mac, s->mac)); + MG_DEBUG(("%lu NDP resolved %M -> %M", c->id, mg_print_ip6, + c->rem.addr.ip, mg_print_mac, s->mac)); c->is_arplooking = 0; mac_resolved(c); } @@ -5343,7 +5356,7 @@ static uint8_t *get_return_mac(struct mg_tcpip_if *ifp, struct mg_addr *rem, } else #endif { - uint32_t rem_ip = rem->ip4; + uint32_t rem_ip = rem->addr.ip4; if (is_udp && (rem_ip == 0xffffffff || rem_ip == (ifp->ip | ~ifp->mask))) return (uint8_t *) broadcast; // global or local broadcast if (ifp->ip != 0 && ((rem_ip & ifp->mask) == (ifp->ip & ifp->mask))) @@ -5369,12 +5382,12 @@ static bool rx_udp(struct mg_tcpip_if *ifp, struct pkt *pkt) { c->rem.port = pkt->udp->sport; #if MG_ENABLE_IPV6 if (c->loc.is_ip6) { - c->rem.ip6[0] = pkt->ip6->src[0], c->rem.ip6[1] = pkt->ip6->src[1], - c->rem.is_ip6 = true; + c->rem.addr.ip6[0] = pkt->ip6->src[0], + c->rem.addr.ip6[1] = pkt->ip6->src[1], c->rem.is_ip6 = true; } else #endif { - c->rem.ip4 = pkt->ip->src; + c->rem.addr.ip4 = pkt->ip->src; } if ((mac = get_return_mac(ifp, &c->rem, true, pkt)) == NULL) return false; // safety net for lousy networks @@ -5413,13 +5426,13 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, } #if MG_ENABLE_IPV6 if (ip_dst->is_ip6) { - ip6 = tx_ip6(ifp, mac_dst, 6, ip_src->ip6, ip_dst->ip6, + ip6 = tx_ip6(ifp, mac_dst, 6, ip_src->addr.ip6, ip_dst->addr.ip6, sizeof(struct tcp) + len); tcp = (struct tcp *) (ip6 + 1); } else #endif { - ip = tx_ip(ifp, mac_dst, 6, ip_src->ip4, ip_dst->ip4, + ip = tx_ip(ifp, mac_dst, 6, ip_src->addr.ip4, ip_dst->addr.ip4, sizeof(struct tcp) + len); tcp = (struct tcp *) (ip + 1); } @@ -5442,9 +5455,6 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, cs = csumup(cs, &ip6->src, sizeof(ip6->src)); cs = csumup(cs, &ip6->dst, sizeof(ip6->dst)); cs += (uint32_t) (6 + n); - MG_VERBOSE(("TCP %M:%hu -> %M:%hu fl %x len %u", mg_print_ip6, &ip6->src, - mg_ntohs(tcp->sport), mg_print_ip6, &ip6->dst, - mg_ntohs(tcp->dport), tcp->flags, len)); } else #endif { @@ -5453,12 +5463,11 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, cs = csumup(cs, &ip->src, sizeof(ip->src)); cs = csumup(cs, &ip->dst, sizeof(ip->dst)); cs = csumup(cs, pseudo, sizeof(pseudo)); - 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)); } tcp->csum = csumfin(cs); } + MG_VERBOSE(("TCP %M -> %M fl %x len %u", mg_print_ip_port, ip_src, + mg_print_ip_port, ip_dst, tcp->flags, len)); return ether_output(ifp, PDIFF(ifp->tx.buf, tcp + 1) + len); } @@ -5471,11 +5480,11 @@ static size_t tx_tcp_ctrlresp(struct mg_tcpip_if *ifp, struct pkt *pkt, memset(&ips, 0, sizeof(ips)); memset(&ipd, 0, sizeof(ipd)); if (pkt->ip != NULL) { - ips.ip4 = pkt->ip->dst; - ipd.ip4 = pkt->ip->src; + ips.addr.ip4 = pkt->ip->dst; + ipd.addr.ip4 = pkt->ip->src; } else { - ips.ip6[0] = pkt->ip6->dst[0], ips.ip6[1] = pkt->ip6->dst[1]; - ipd.ip6[0] = pkt->ip6->src[0], ipd.ip6[1] = pkt->ip6->src[1]; + ips.addr.ip6[0] = pkt->ip6->dst[0], ips.addr.ip6[1] = pkt->ip6->dst[1]; + ipd.addr.ip6[0] = pkt->ip6->src[0], ipd.addr.ip6[1] = pkt->ip6->src[1]; ips.is_ip6 = true; ipd.is_ip6 = true; } @@ -5505,16 +5514,16 @@ static struct mg_connection *accept_conn(struct mg_connection *lsn, s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq); #if MG_ENABLE_IPV6 if (lsn->loc.is_ip6) { - c->rem.ip6[0] = pkt->ip6->src[0], c->rem.ip6[1] = pkt->ip6->src[1], - c->rem.is_ip6 = true; - c->loc.ip6[0] = c->mgr->ifp->ip6[0], c->loc.ip6[1] = c->mgr->ifp->ip6[1], - c->loc.is_ip6 = true; + c->rem.addr.ip6[0] = pkt->ip6->src[0], + c->rem.addr.ip6[1] = pkt->ip6->src[1], c->rem.is_ip6 = true; + c->loc.addr.ip6[0] = c->mgr->ifp->ip6[0], + c->loc.addr.ip6[1] = c->mgr->ifp->ip6[1], c->loc.is_ip6 = true; // TODO(): compare lsn to link-local, or rem as link-local: use ll instead } else #endif { - c->rem.ip4 = pkt->ip->src; - c->loc.ip4 = c->mgr->ifp->ip; + c->rem.addr.ip4 = pkt->ip->src; + c->loc.addr.ip4 = c->mgr->ifp->ip; } c->rem.port = pkt->tcp->sport; c->loc.port = lsn->loc.port; @@ -5576,12 +5585,13 @@ static bool udp_send(struct mg_connection *c, const void *buf, size_t len) { memset(&ips, 0, sizeof(ips)); #if MG_ENABLE_IPV6 if (c->loc.is_ip6) { - ips.ip6[0] = ifp->ip6[0], ips.ip6[1] = ifp->ip6[1], ips.is_ip6 = true; + ips.addr.ip6[0] = ifp->ip6[0], ips.addr.ip6[1] = ifp->ip6[1], + ips.is_ip6 = true; // TODO(): detect link-local (c->rem) and use it } else #endif { - ips.ip4 = ifp->ip; + ips.addr.ip4 = ifp->ip; } ips.port = c->loc.port; return tx_udp(ifp, s->mac, &ips, &c->rem, buf, len); @@ -6319,12 +6329,12 @@ void mg_connect_resolved(struct mg_connection *c) { c->loc.port = mg_htons(ifp->eport++); #if MG_ENABLE_IPV6 if (c->rem.is_ip6) { - c->loc.ip6[0] = ifp->ip6[0], c->loc.ip6[1] = ifp->ip6[1], + c->loc.addr.ip6[0] = ifp->ip6[0], c->loc.addr.ip6[1] = ifp->ip6[1], c->loc.is_ip6 = true; } else #endif { - c->loc.ip4 = ifp->ip; + c->loc.addr.ip4 = ifp->ip; } MG_DEBUG(("%lu %M -> %M", c->id, mg_print_ip_port, &c->loc, mg_print_ip_port, &c->rem)); @@ -6333,21 +6343,21 @@ void mg_connect_resolved(struct mg_connection *c) { #if MG_ENABLE_IPV6 if (c->rem.is_ip6) { if (c->is_udp && - MG_IP6MATCH(c->rem.ip6, ip6_allnodes.u)) { // local broadcast + MG_IP6MATCH(c->rem.addr.ip6, ip6_allnodes.u)) { // local broadcast struct connstate *s = (struct connstate *) (c + 1); memcpy(s->mac, ip6mac_allnodes, sizeof(s->mac)); mac_resolved(c); - } else if (c->rem.ip6[0] == ifp->ip6[0] && // TODO(): HANDLE PREFIX *** - !MG_IP6MATCH(c->rem.ip6, + } else if (c->rem.addr.ip6[0] == ifp->ip6[0] && // TODO(): HANDLE PREFIX *** + !MG_IP6MATCH(c->rem.addr.ip6, ifp->gw6)) { // skip if gw (onstate6change -> NS) // If we're in the same LAN, fire a Neighbor Solicitation MG_DEBUG(("%lu NS lookup...", c->id)); - tx_ndp_ns(ifp, c->rem.ip6, ifp->mac); + tx_ndp_ns(ifp, c->rem.addr.ip6, ifp->mac); settmout(c, MIP_TTYPE_ARP); c->is_arplooking = 1; - } else if (c->is_udp && *((uint8_t *) c->rem.ip6) == 0xFF) { // multicast + } else if (c->is_udp && *((uint8_t *) c->rem.addr.ip6) == 0xFF) { // multicast struct connstate *s = (struct connstate *) (c + 1); - ip6_mcastmac(s->mac, c->rem.ip6); + ip6_mcastmac(s->mac, c->rem.addr.ip6); mac_resolved(c); } else if (ifp->gw6_ready) { struct connstate *s = (struct connstate *) (c + 1); @@ -6359,7 +6369,7 @@ void mg_connect_resolved(struct mg_connection *c) { } else #endif { - uint32_t rem_ip = c->rem.ip4; + uint32_t rem_ip = c->rem.addr.ip4; if (c->is_udp && (rem_ip == 0xffffffff || rem_ip == (ifp->ip | ~ifp->mask))) { struct connstate *s = (struct connstate *) (c + 1); @@ -8711,8 +8721,10 @@ void mg_pfn_iobuf(char ch, void *param) { } size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap) { - struct mg_iobuf io = {(uint8_t *) buf, len, 0, 0}; - size_t n = mg_vxprintf(mg_putchar_iobuf_static, &io, fmt, ap); + struct mg_iobuf io = {0, 0, 0, 0}; + size_t n; + io.buf = (uint8_t *) buf, io.size = len; + n = mg_vxprintf(mg_putchar_iobuf_static, &io, fmt, ap); if (n < len) buf[n] = '\0'; return n; } @@ -8769,8 +8781,8 @@ size_t mg_print_ip6(void (*out)(char, void *), void *arg, va_list *ap) { size_t mg_print_ip(void (*out)(char, void *), void *arg, va_list *ap) { struct mg_addr *addr = va_arg(*ap, struct mg_addr *); - if (addr->is_ip6) return print_ip6(out, arg, (uint16_t *) addr->ip); - return print_ip4(out, arg, (uint8_t *) &addr->ip); + if (addr->is_ip6) return print_ip6(out, arg, (uint16_t *) addr->addr.ip); + return print_ip4(out, arg, (uint8_t *) &addr->addr.ip); } size_t mg_print_ip_port(void (*out)(char, void *), void *arg, va_list *ap) { @@ -8818,7 +8830,8 @@ static size_t bcpy(void (*out)(char, void *), void *arg, uint8_t *buf, for (i = 0; i < len; i += 3) { uint8_t c1 = buf[i], c2 = i + 1 < len ? buf[i + 1] : 0, c3 = i + 2 < len ? buf[i + 2] : 0; - char tmp[4] = {t[c1 >> 2], t[(c1 & 3) << 4 | (c2 >> 4)], '=', '='}; + char tmp[4] = {0, 0, '=', '='}; + tmp[0] = t[c1 >> 2], tmp[1] = t[(c1 & 3) << 4 | (c2 >> 4)]; if (i + 1 < len) tmp[2] = t[(c2 & 15) << 2 | (c3 >> 6)]; if (i + 2 < len) tmp[3] = t[c3 & 63]; for (j = 0; j < sizeof(tmp) && tmp[j] != '\0'; j++) out(tmp[j], arg); @@ -9444,6 +9457,35 @@ void mg_hmac_sha256(uint8_t dst[32], uint8_t *key, size_t keysz, uint8_t *data, #define sig164(x) (rotr64(x, 19) ^ rotr64(x, 61) ^ ((x) >> 6)) static const uint64_t mg_sha256_k2[80] = { +#if defined(__DCC__) + 0x428a2f98d728ae22ull, 0x7137449123ef65cdull, 0xb5c0fbcfec4d3b2full, + 0xe9b5dba58189dbbcull, 0x3956c25bf348b538ull, 0x59f111f1b605d019ull, + 0x923f82a4af194f9bull, 0xab1c5ed5da6d8118ull, 0xd807aa98a3030242ull, + 0x12835b0145706fbeull, 0x243185be4ee4b28cull, 0x550c7dc3d5ffb4e2ull, + 0x72be5d74f27b896full, 0x80deb1fe3b1696b1ull, 0x9bdc06a725c71235ull, + 0xc19bf174cf692694ull, 0xe49b69c19ef14ad2ull, 0xefbe4786384f25e3ull, + 0x0fc19dc68b8cd5b5ull, 0x240ca1cc77ac9c65ull, 0x2de92c6f592b0275ull, + 0x4a7484aa6ea6e483ull, 0x5cb0a9dcbd41fbd4ull, 0x76f988da831153b5ull, + 0x983e5152ee66dfabull, 0xa831c66d2db43210ull, 0xb00327c898fb213full, + 0xbf597fc7beef0ee4ull, 0xc6e00bf33da88fc2ull, 0xd5a79147930aa725ull, + 0x06ca6351e003826full, 0x142929670a0e6e70ull, 0x27b70a8546d22ffcull, + 0x2e1b21385c26c926ull, 0x4d2c6dfc5ac42aedull, 0x53380d139d95b3dfull, + 0x650a73548baf63deull, 0x766a0abb3c77b2a8ull, 0x81c2c92e47edaee6ull, + 0x92722c851482353bull, 0xa2bfe8a14cf10364ull, 0xa81a664bbc423001ull, + 0xc24b8b70d0f89791ull, 0xc76c51a30654be30ull, 0xd192e819d6ef5218ull, + 0xd69906245565a910ull, 0xf40e35855771202aull, 0x106aa07032bbd1b8ull, + 0x19a4c116b8d2d0c8ull, 0x1e376c085141ab53ull, 0x2748774cdf8eeb99ull, + 0x34b0bcb5e19b48a8ull, 0x391c0cb3c5c95a63ull, 0x4ed8aa4ae3418acbull, + 0x5b9cca4f7763e373ull, 0x682e6ff3d6b2b8a3ull, 0x748f82ee5defb2fcull, + 0x78a5636f43172f60ull, 0x84c87814a1f0ab72ull, 0x8cc702081a6439ecull, + 0x90befffa23631e28ull, 0xa4506cebde82bde9ull, 0xbef9a3f7b2c67915ull, + 0xc67178f2e372532bull, 0xca273eceea26619cull, 0xd186b8c721c0c207ull, + 0xeada7dd6cde0eb1eull, 0xf57d4f7fee6ed178ull, 0x06f067aa72176fbaull, + 0x0a637dc5a2c898a6ull, 0x113f9804bef90daeull, 0x1b710b35131c471bull, + 0x28db77f523047d84ull, 0x32caab7b40c72493ull, 0x3c9ebe0a15c9bebcull, + 0x431d67c49c100d4cull, 0x4cc5d4becb3e42b6ull, 0x597f299cfc657e2aull, + 0x5fcb6fab3ad6faecull, 0x6c44198c4a475817ull +#else 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, @@ -9470,7 +9512,9 @@ static const uint64_t mg_sha256_k2[80] = { 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, - 0x5fcb6fab3ad6faec, 0x6c44198c4a475817}; + 0x5fcb6fab3ad6faec, 0x6c44198c4a475817 +#endif +}; static void mg_sha384_transform(mg_sha384_ctx *ctx, const uint8_t data[]) { uint64_t m[80]; @@ -9521,6 +9565,16 @@ void mg_sha384_init(mg_sha384_ctx *ctx) { ctx->datalen = 0; ctx->bitlen[0] = 0; ctx->bitlen[1] = 0; +#if defined(__DCC__) + ctx->state[0] = 0xcbbb9d5dc1059ed8ull; + ctx->state[1] = 0x629a292a367cd507ull; + ctx->state[2] = 0x9159015a3070dd17ull; + ctx->state[3] = 0x152fecd8f70e5939ull; + ctx->state[4] = 0x67332667ffc00b31ull; + ctx->state[5] = 0x8eb44a8768581511ull; + ctx->state[6] = 0xdb0c2e0d64f98fa7ull; + ctx->state[7] = 0x47b5481dbefa4fa4ull; +#else ctx->state[0] = 0xcbbb9d5dc1059ed8; ctx->state[1] = 0x629a292a367cd507; ctx->state[2] = 0x9159015a3070dd17; @@ -9529,6 +9583,7 @@ void mg_sha384_init(mg_sha384_ctx *ctx) { ctx->state[5] = 0x8eb44a8768581511; ctx->state[6] = 0xdb0c2e0d64f98fa7; ctx->state[7] = 0x47b5481dbefa4fa4; +#endif } void mg_sha384_update(mg_sha384_ctx *ctx, const uint8_t *data, size_t len) { @@ -9751,13 +9806,13 @@ static socklen_t tousa(struct mg_addr *a, union usa *usa) { memset(usa, 0, sizeof(*usa)); usa->sin.sin_family = AF_INET; usa->sin.sin_port = a->port; - memcpy(&usa->sin.sin_addr, a->ip, sizeof(uint32_t)); + memcpy(&usa->sin.sin_addr, a->addr.ip, sizeof(uint32_t)); #if MG_ENABLE_IPV6 if (a->is_ip6) { usa->sin.sin_family = AF_INET6; usa->sin6.sin6_port = a->port; usa->sin6.sin6_scope_id = a->scope_id; - memcpy(&usa->sin6.sin6_addr, a->ip, sizeof(a->ip)); + memcpy(&usa->sin6.sin6_addr, a->addr.ip, sizeof(a->addr.ip)); len = sizeof(usa->sin6); } #endif @@ -9767,10 +9822,10 @@ static socklen_t tousa(struct mg_addr *a, union usa *usa) { static void tomgaddr(union usa *usa, struct mg_addr *a, bool is_ip6) { a->is_ip6 = is_ip6; a->port = usa->sin.sin_port; - memcpy(&a->ip, &usa->sin.sin_addr, sizeof(uint32_t)); + memcpy(&a->addr.ip, &usa->sin.sin_addr, sizeof(uint32_t)); #if MG_ENABLE_IPV6 if (is_ip6) { - memcpy(a->ip, &usa->sin6.sin6_addr, sizeof(a->ip)); + memcpy(a->addr.ip, &usa->sin6.sin6_addr, sizeof(a->addr.ip)); a->port = usa->sin6.sin6_port; a->scope_id = (uint8_t) usa->sin6.sin6_scope_id; } @@ -10582,12 +10637,14 @@ void mg_http_serve_ssi(struct mg_connection *c, const char *root, struct mg_str mg_str_s(const char *s) { - struct mg_str str = {(char *) s, s == NULL ? 0 : strlen(s)}; + struct mg_str str; + str.buf = (char *) s, str.len = (s == NULL) ? 0 : strlen(s); return str; } struct mg_str mg_str_n(const char *s, size_t n) { - struct mg_str str = {(char *) s, n}; + struct mg_str str; + str.buf = (char *) s, str.len = n; return str; } @@ -13161,7 +13218,7 @@ static int mg_tls_verify_cert_san(const uint8_t *der, size_t dersz, while (mg_der_next(&field, &name) > 0) { if (name.type == 0x87 && name.len == 4) { // this is an IPv4 address MG_DEBUG(("Found SAN, IP: %M", mg_print_ip4, name.value)); - if (!server_ip->is_ip6 && *((uint32_t *) name.value) == server_ip->ip4) + if (!server_ip->is_ip6 && *((uint32_t *) name.value) == server_ip->addr.ip4) return 1; // and matches the one we're connected to } else { // this is a text SAN MG_DEBUG(("Found SAN, (%u): %.*s", name.type, name.len, name.value)); @@ -21038,7 +21095,7 @@ int mg_check_ip_acl(struct mg_str acl, struct mg_addr *remote_ip) { if (remote_ip->is_ip6) { return -1; // TODO(): handle IPv6 ACL and addresses } else { // IPv4 - memcpy((void *) &remote_ip4, remote_ip->ip, sizeof(remote_ip4)); + memcpy((void *) &remote_ip4, remote_ip->addr.ip, sizeof(remote_ip4)); while (mg_span(acl, &entry, &acl, ',')) { uint32_t net, mask; if (entry.buf[0] != '+' && entry.buf[0] != '-') return -1; @@ -21052,7 +21109,7 @@ int mg_check_ip_acl(struct mg_str acl, struct mg_addr *remote_ip) { bool mg_path_is_sane(const struct mg_str path) { const char *s = path.buf; size_t n = path.len; - if (path.buf[0] == '~') return false; // Starts with ~ + if (path.buf[0] == '~') return false; // Starts with ~ if (path.buf[0] == '.' && path.buf[1] == '.') return false; // Starts with .. for (; s[0] != '\0' && n > 0; s++, n--) { if ((s[0] == '/' || s[0] == '\\') && n >= 2) { // Subdir? @@ -21131,7 +21188,6 @@ void mg_delayms(unsigned int ms) { while (mg_millis() < to) (void) 0; } - #if MG_ENABLE_CUSTOM_CALLOC #else void *mg_calloc(size_t count, size_t size) { @@ -21357,9 +21413,13 @@ static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data) { while (ws_process(c->recv.buf + ofs, c->recv.len - ofs, &msg) > 0) { char *s = (char *) c->recv.buf + ofs + msg.header_len; - struct mg_ws_message m = {{s, msg.data_len}, msg.flags}; - size_t len = msg.header_len + msg.data_len; - uint8_t final = msg.flags & 128, op = msg.flags & 15; + struct mg_ws_message m; + size_t len; + uint8_t final, op; + m.data.buf = s, m.data.len = msg.data_len, m.flags = msg.flags; + len = msg.header_len + msg.data_len; + final = msg.flags & 128; + op = msg.flags & 15; // MG_VERBOSE ("fin %d op %d len %d [%.*s]", final, op, // (int) m.data.len, (int) m.data.len, m.data.buf)); switch (op) { diff --git a/mongoose.h b/mongoose.h index b26efd17..f70ff72c 100644 --- a/mongoose.h +++ b/mongoose.h @@ -1267,12 +1267,18 @@ void mg_log_set_fn(mg_pfn_t fn, void *param); #define mg_log_set(level_) mg_log_level = (level_) #if MG_ENABLE_LOG -#define MG_LOG(level, args) \ - do { \ - if ((level) <= mg_log_level) { \ - mg_log_prefix((level), __FILE__, __LINE__, __func__); \ - mg_log args; \ - } \ +#if !defined(_MSC_VER) && \ + (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) +#define MG___FUNC__ "" +#else +#define MG___FUNC__ __func__ // introduced in C99 +#endif +#define MG_LOG(level, args) \ + do { \ + if ((level) <= mg_log_level) { \ + mg_log_prefix((level), __FILE__, __LINE__, MG___FUNC__); \ + mg_log args; \ + } \ } while (0) #else #define MG_LOG(level, args) \ @@ -1663,11 +1669,11 @@ struct mg_dns { }; struct mg_addr { - union { // Holds IPv4 or IPv6 address, in network byte order + union { // Holds IPv4 or IPv6 address, in network byte order uint8_t ip[16]; uint32_t ip4; uint64_t ip6[2]; - }; + } addr; uint16_t port; // TCP or UDP port in network byte order uint8_t scope_id; // IPv6 scope ID bool is_ip6; // True when address is IPv6 address @@ -2954,7 +2960,6 @@ struct mg_dns_rr { uint16_t alen; // Address length }; - // DNS-SD response record struct mg_dnssd_record { struct mg_str srvcproto; // service.proto, service name @@ -2966,8 +2971,8 @@ struct mg_dnssd_record { struct mg_mdns_req { struct mg_dns_rr *rr; struct mg_dnssd_record *r; - struct mg_str reqname; // requested name in RR - struct mg_str respname; // actual name in response + struct mg_str reqname; // requested name in RR + struct mg_str respname; // actual name in response struct mg_addr addr; bool is_listing; bool is_resp; @@ -2979,8 +2984,9 @@ void mg_resolve_cancel(struct mg_connection *); bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *); size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs, bool is_question, struct mg_dns_rr *); - -struct mg_connection *mg_mdns_listen(struct mg_mgr *mgr, mg_event_handler_t fn, void *fn_data); + +struct mg_connection *mg_mdns_listen(struct mg_mgr *mgr, mg_event_handler_t fn, + void *fn_data); diff --git a/src/dns.c b/src/dns.c index 8bcd78b8..1857738e 100644 --- a/src/dns.c +++ b/src/dns.c @@ -136,12 +136,12 @@ bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *dm) { if (rr.alen == 4 && rr.atype == 1 && rr.aclass == 1) { dm->addr.is_ip6 = false; - memcpy(&dm->addr.ip, &buf[ofs - 4], 4); + memcpy(&dm->addr.addr.ip, &buf[ofs - 4], 4); dm->resolved = true; break; // Return success } else if (rr.alen == 16 && rr.atype == 28 && rr.aclass == 1) { dm->addr.is_ip6 = true; - memcpy(&dm->addr.ip, &buf[ofs - 16], 16); + memcpy(&dm->addr.addr.ip, &buf[ofs - 16], 16); dm->resolved = true; break; // Return success } diff --git a/src/dns.h b/src/dns.h index 32e484aa..be5e1bec 100644 --- a/src/dns.h +++ b/src/dns.h @@ -31,7 +31,6 @@ struct mg_dns_rr { uint16_t alen; // Address length }; - // DNS-SD response record struct mg_dnssd_record { struct mg_str srvcproto; // service.proto, service name @@ -43,8 +42,8 @@ struct mg_dnssd_record { struct mg_mdns_req { struct mg_dns_rr *rr; struct mg_dnssd_record *r; - struct mg_str reqname; // requested name in RR - struct mg_str respname; // actual name in response + struct mg_str reqname; // requested name in RR + struct mg_str respname; // actual name in response struct mg_addr addr; bool is_listing; bool is_resp; @@ -56,5 +55,6 @@ void mg_resolve_cancel(struct mg_connection *); bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *); size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs, bool is_question, struct mg_dns_rr *); - -struct mg_connection *mg_mdns_listen(struct mg_mgr *mgr, mg_event_handler_t fn, void *fn_data); + +struct mg_connection *mg_mdns_listen(struct mg_mgr *mgr, mg_event_handler_t fn, + void *fn_data); diff --git a/src/fmt.c b/src/fmt.c index e16f7f46..a867c295 100644 --- a/src/fmt.c +++ b/src/fmt.c @@ -22,7 +22,8 @@ static int xisinf(double x) { union { double f; uint64_t u; - } ieee754 = {x}; + } ieee754; + ieee754.f = x; return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 && ((unsigned) ieee754.u == 0); } @@ -31,7 +32,8 @@ static int xisnan(double x) { union { double f; uint64_t u; - } ieee754 = {x}; + } ieee754; + ieee754.f = x; return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) + ((unsigned) ieee754.u != 0) > 0x7ff00000; @@ -99,7 +101,7 @@ static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width, bool tz) { } while (tz && n > 0 && buf[s + n - 1] == '0') n--; // Trim trailing zeroes - if (tz && n > 0 && buf[s + n - 1] == '.') n--; // Trim trailing dot + if (tz && n > 0 && buf[s + n - 1] == '.') n--; // Trim trailing dot n += s; if (n >= (int) sizeof(buf)) n = (int) sizeof(buf) - 1; buf[n] = '\0'; @@ -129,7 +131,7 @@ static size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex) { } static size_t scpy(void (*out)(char, void *), void *ptr, char *buf, - size_t len) { + size_t len) { size_t i = 0; while (i < len && buf[i] != '\0') out(buf[i++], ptr); return i; diff --git a/src/fs.c b/src/fs.c index 9d00c8e1..6068ca21 100644 --- a/src/fs.c +++ b/src/fs.c @@ -86,7 +86,8 @@ static void mg_fs_ls_fn(const char *filename, void *param) { } bool mg_fs_ls(struct mg_fs *fs, const char *path, char *buf, size_t len) { - struct mg_str s = {buf, len}; + struct mg_str s; + s.buf = buf, s.len = len; fs->ls(path, mg_fs_ls_fn, &s); return buf[0] != '\0'; } diff --git a/src/log.h b/src/log.h index 18fd2c37..68970558 100644 --- a/src/log.h +++ b/src/log.h @@ -16,12 +16,18 @@ void mg_log_set_fn(mg_pfn_t fn, void *param); #define mg_log_set(level_) mg_log_level = (level_) #if MG_ENABLE_LOG -#define MG_LOG(level, args) \ - do { \ - if ((level) <= mg_log_level) { \ - mg_log_prefix((level), __FILE__, __LINE__, __func__); \ - mg_log args; \ - } \ +#if !defined(_MSC_VER) && \ + (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) +#define MG___FUNC__ "" +#else +#define MG___FUNC__ __func__ // introduced in C99 +#endif +#define MG_LOG(level, args) \ + do { \ + if ((level) <= mg_log_level) { \ + mg_log_prefix((level), __FILE__, __LINE__, MG___FUNC__); \ + mg_log args; \ + } \ } while (0) #else #define MG_LOG(level, args) \ diff --git a/src/mqtt.c b/src/mqtt.c index 9e7f1481..a4c82015 100644 --- a/src/mqtt.c +++ b/src/mqtt.c @@ -266,7 +266,8 @@ void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts) { char client_id[21]; struct mg_str cid = opts->client_id; size_t total_len = 7 + 1 + 2 + 2; - uint8_t hdr[8] = {0, 4, 'M', 'Q', 'T', 'T', opts->version, 0}; + uint8_t hdr[8] = {0, 4, 'M', 'Q', 'T', 'T', 0, 0}; + hdr[6] = opts->version; if (cid.len == 0) { mg_random_str(client_id, sizeof(client_id) - 1); diff --git a/src/net.c b/src/net.c index 50231335..44203651 100644 --- a/src/net.c +++ b/src/net.c @@ -31,14 +31,14 @@ size_t mg_printf(struct mg_connection *c, const char *fmt, ...) { static bool mg_atonl(struct mg_str str, struct mg_addr *addr) { uint32_t localhost = mg_htonl(0x7f000001); if (mg_strcasecmp(str, mg_str("localhost")) != 0) return false; - memcpy(addr->ip, &localhost, sizeof(uint32_t)); + memcpy(addr->addr.ip, &localhost, sizeof(uint32_t)); addr->is_ip6 = false; return true; } static bool mg_atone(struct mg_str str, struct mg_addr *addr) { if (str.len > 0) return false; - memset(addr->ip, 0, sizeof(addr->ip)); + memset(addr->addr.ip, 0, sizeof(addr->addr.ip)); addr->is_ip6 = false; return true; } @@ -59,7 +59,7 @@ static bool mg_aton4(struct mg_str str, struct mg_addr *addr) { } } if (num_dots != 3 || str.buf[i - 1] == '.') return false; - memcpy(&addr->ip, data, sizeof(data)); + memcpy(&addr->addr.ip, data, sizeof(data)); addr->is_ip6 = false; return true; } @@ -74,10 +74,10 @@ static bool mg_v4mapped(struct mg_str str, struct mg_addr *addr) { } // struct mg_str s = mg_str_n(&str.buf[7], str.len - 7); if (!mg_aton4(mg_str_n(&str.buf[7], str.len - 7), addr)) return false; - memcpy(&ipv4, addr->ip, sizeof(ipv4)); - memset(addr->ip, 0, sizeof(addr->ip)); - addr->ip[10] = addr->ip[11] = 255; - memcpy(&addr->ip[12], &ipv4, 4); + memcpy(&ipv4, addr->addr.ip, sizeof(ipv4)); + memset(addr->addr.ip, 0, sizeof(addr->addr.ip)); + addr->addr.ip[10] = addr->addr.ip[11] = 255; + memcpy(&addr->addr.ip[12], &ipv4, 4); addr->is_ip6 = true; return true; } @@ -95,8 +95,8 @@ static bool mg_aton6(struct mg_str str, struct mg_addr *addr) { if (i > j + 3) return false; // MG_DEBUG(("%lu %lu [%.*s]", i, j, (int) (i - j + 1), &str.buf[j])); mg_str_to_num(mg_str_n(&str.buf[j], i - j + 1), 16, &val, sizeof(val)); - addr->ip[n] = (uint8_t) ((val >> 8) & 255); - addr->ip[n + 1] = (uint8_t) (val & 255); + addr->addr.ip[n] = (uint8_t) ((val >> 8) & 255); + addr->addr.ip[n + 1] = (uint8_t) (val & 255); } else if (str.buf[i] == ':') { j = i + 1; if (i > 0 && str.buf[i - 1] == ':') { @@ -106,8 +106,8 @@ static bool mg_aton6(struct mg_str str, struct mg_addr *addr) { n += 2; } if (n > 14) return false; - addr->ip[n] = addr->ip[n + 1] = 0; // For trailing :: - } else if (str.buf[i] == '%') { // Scope ID, last in string + addr->addr.ip[n] = addr->addr.ip[n + 1] = 0; // For trailing :: + } else if (str.buf[i] == '%') { // Scope ID, last in string if (mg_str_to_num(mg_str_n(&str.buf[i + 1], str.len - i - 1), 10, &addr->scope_id, sizeof(uint8_t))) { addr->is_ip6 = true; @@ -121,8 +121,8 @@ static bool mg_aton6(struct mg_str str, struct mg_addr *addr) { } if (n < 14 && dc == 42) return false; if (n < 14) { - memmove(&addr->ip[dc + (14 - n)], &addr->ip[dc], n - dc + 2); - memset(&addr->ip[dc], 0, 14 - n); + memmove(&addr->addr.ip[dc + (14 - n)], &addr->addr.ip[dc], n - dc + 2); + memset(&addr->addr.ip[dc], 0, 14 - n); } addr->is_ip6 = true; diff --git a/src/net.h b/src/net.h index e6088204..47f0f566 100644 --- a/src/net.h +++ b/src/net.h @@ -14,11 +14,11 @@ struct mg_dns { }; struct mg_addr { - union { // Holds IPv4 or IPv6 address, in network byte order + union { // Holds IPv4 or IPv6 address, in network byte order uint8_t ip[16]; uint32_t ip4; uint64_t ip6[2]; - }; + } addr; uint16_t port; // TCP or UDP port in network byte order uint8_t scope_id; // IPv6 scope ID bool is_ip6; // True when address is IPv6 address diff --git a/src/net_builtin.c b/src/net_builtin.c index 40c05517..1458d58a 100644 --- a/src/net_builtin.c +++ b/src/net_builtin.c @@ -34,7 +34,11 @@ struct connstate { bool twclosure; // 3-way closure done }; +#if defined(__DCC__) +#pragma pack(1) +#else #pragma pack(push, 1) +#endif struct lcp { uint8_t addr, ctrl, proto[2], code, id, len[2]; @@ -153,7 +157,11 @@ struct dhcp6 { uint8_t options[30 + sizeof(((struct mg_tcpip_if *) 0)->dhcp_name)]; }; +#if defined(__DCC__) +#pragma pack(0) +#else #pragma pack(pop) +#endif // pkt is 8-bit aligned, pointers to headers hint compilers to generate // byte-copy code for micros with alignment constraints @@ -356,14 +364,14 @@ static bool tx_udp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, #if MG_ENABLE_IPV6 struct ip6 *ip6 = NULL; if (ip_dst->is_ip6) { - ip6 = tx_ip6(ifp, mac_dst, 17, ip_src->ip6, ip_dst->ip6, + ip6 = tx_ip6(ifp, mac_dst, 17, ip_src->addr.ip6, ip_dst->addr.ip6, len + sizeof(struct udp)); udp = (struct udp *) (ip6 + 1); eth_len = sizeof(struct eth) + sizeof(*ip6) + sizeof(*udp) + len; } else #endif { - ip = tx_ip(ifp, mac_dst, 17, ip_src->ip4, ip_dst->ip4, + ip = tx_ip(ifp, mac_dst, 17, ip_src->addr.ip4, ip_dst->addr.ip4, len + sizeof(struct udp)); udp = (struct udp *) (ip + 1); eth_len = sizeof(struct eth) + sizeof(*ip) + sizeof(*udp) + len; @@ -395,10 +403,10 @@ static bool tx_udp4(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src, const void *buf, size_t len) { struct mg_addr ips, ipd; memset(&ips, 0, sizeof(ips)); - ips.ip4 = ip_src; + ips.addr.ip4 = ip_src; ips.port = sport; memset(&ipd, 0, sizeof(ipd)); - ipd.ip4 = ip_dst; + ipd.addr.ip4 = ip_dst; ipd.port = dport; return tx_udp(ifp, mac_dst, &ips, &ipd, buf, len); } @@ -470,11 +478,11 @@ static struct mg_connection *getpeer(struct mg_mgr *mgr, struct pkt *pkt, bool lsn) { struct mg_connection *c = NULL; for (c = mgr->conns; c != NULL; c = c->next) { - if (c->is_arplooking && pkt->arp && pkt->arp->spa == c->rem.ip4) break; + if (c->is_arplooking && pkt->arp && pkt->arp->spa == c->rem.addr.ip4) break; #if MG_ENABLE_IPV6 if (c->is_arplooking && pkt->icmp6 && pkt->icmp6->type == 136) { struct ndp_na *na = (struct ndp_na *) (pkt->icmp6 + 1); - if (MG_IP6MATCH(na->addr, c->rem.ip6)) break; + if (MG_IP6MATCH(na->addr, c->rem.addr.ip6)) break; } #endif if (c->is_udp && pkt->udp && c->loc.port == pkt->udp->dport && @@ -526,8 +534,8 @@ static void rx_arp(struct mg_tcpip_if *ifp, struct pkt *pkt) { if (c != NULL && c->is_arplooking) { struct connstate *s = (struct connstate *) (c + 1); memcpy(s->mac, pkt->arp->sha, sizeof(s->mac)); - MG_DEBUG(("%lu ARP resolved %M -> %M", c->id, mg_print_ip4, c->rem.ip, - mg_print_mac, s->mac)); + MG_DEBUG(("%lu ARP resolved %M -> %M", c->id, mg_print_ip4, + c->rem.addr.ip, mg_print_mac, s->mac)); c->is_arplooking = 0; mac_resolved(c); } @@ -542,7 +550,7 @@ static void rx_icmp(struct mg_tcpip_if *ifp, struct pkt *pkt) { struct ip *ip; struct icmp *icmp; struct mg_addr ips; - ips.ip4 = pkt->ip->src; + ips.addr.ip4 = pkt->ip->src; ips.is_ip6 = false; if (get_return_mac(ifp, &ips, false, pkt) == NULL) return; // safety net for lousy networks @@ -640,13 +648,14 @@ static void rx_dhcp_server(struct mg_tcpip_if *ifp, struct pkt *pkt) { if (op == 1 || op == 3) { // DHCP Discover or DHCP Request uint8_t msg = op == 1 ? 2 : 5; // Message type: DHCP OFFER or DHCP ACK uint8_t opts[] = { - 53, 1, msg, // Message type + 53, 1, 0, // Message type 1, 4, 0, 0, 0, 0, // Subnet mask 54, 4, 0, 0, 0, 0, // Server ID 12, 3, 'm', 'i', 'p', // Host name: "mip" 51, 4, 255, 255, 255, 255, // Lease time 255 // End of options }; + opts[2] = msg; memcpy(&res.hwaddr, pkt->dhcp->hwaddr, 6); memcpy(opts + 5, &ifp->mask, sizeof(ifp->mask)); memcpy(opts + 11, &ifp->ip, sizeof(ifp->ip)); @@ -742,8 +751,8 @@ static void rx_ndp_na(struct mg_tcpip_if *ifp, struct pkt *pkt) { if (c != NULL && c->is_arplooking) { struct connstate *s = (struct connstate *) (c + 1); memcpy(s->mac, opts, sizeof(s->mac)); - MG_DEBUG(("%lu NDP resolved %M -> %M", c->id, mg_print_ip6, c->rem.ip, - mg_print_mac, s->mac)); + MG_DEBUG(("%lu NDP resolved %M -> %M", c->id, mg_print_ip6, + c->rem.addr.ip, mg_print_mac, s->mac)); c->is_arplooking = 0; mac_resolved(c); } @@ -955,7 +964,7 @@ static uint8_t *get_return_mac(struct mg_tcpip_if *ifp, struct mg_addr *rem, } else #endif { - uint32_t rem_ip = rem->ip4; + uint32_t rem_ip = rem->addr.ip4; if (is_udp && (rem_ip == 0xffffffff || rem_ip == (ifp->ip | ~ifp->mask))) return (uint8_t *) broadcast; // global or local broadcast if (ifp->ip != 0 && ((rem_ip & ifp->mask) == (ifp->ip & ifp->mask))) @@ -981,12 +990,12 @@ static bool rx_udp(struct mg_tcpip_if *ifp, struct pkt *pkt) { c->rem.port = pkt->udp->sport; #if MG_ENABLE_IPV6 if (c->loc.is_ip6) { - c->rem.ip6[0] = pkt->ip6->src[0], c->rem.ip6[1] = pkt->ip6->src[1], - c->rem.is_ip6 = true; + c->rem.addr.ip6[0] = pkt->ip6->src[0], + c->rem.addr.ip6[1] = pkt->ip6->src[1], c->rem.is_ip6 = true; } else #endif { - c->rem.ip4 = pkt->ip->src; + c->rem.addr.ip4 = pkt->ip->src; } if ((mac = get_return_mac(ifp, &c->rem, true, pkt)) == NULL) return false; // safety net for lousy networks @@ -1025,13 +1034,13 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, } #if MG_ENABLE_IPV6 if (ip_dst->is_ip6) { - ip6 = tx_ip6(ifp, mac_dst, 6, ip_src->ip6, ip_dst->ip6, + ip6 = tx_ip6(ifp, mac_dst, 6, ip_src->addr.ip6, ip_dst->addr.ip6, sizeof(struct tcp) + len); tcp = (struct tcp *) (ip6 + 1); } else #endif { - ip = tx_ip(ifp, mac_dst, 6, ip_src->ip4, ip_dst->ip4, + ip = tx_ip(ifp, mac_dst, 6, ip_src->addr.ip4, ip_dst->addr.ip4, sizeof(struct tcp) + len); tcp = (struct tcp *) (ip + 1); } @@ -1054,9 +1063,6 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, cs = csumup(cs, &ip6->src, sizeof(ip6->src)); cs = csumup(cs, &ip6->dst, sizeof(ip6->dst)); cs += (uint32_t) (6 + n); - MG_VERBOSE(("TCP %M:%hu -> %M:%hu fl %x len %u", mg_print_ip6, &ip6->src, - mg_ntohs(tcp->sport), mg_print_ip6, &ip6->dst, - mg_ntohs(tcp->dport), tcp->flags, len)); } else #endif { @@ -1065,12 +1071,11 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, cs = csumup(cs, &ip->src, sizeof(ip->src)); cs = csumup(cs, &ip->dst, sizeof(ip->dst)); cs = csumup(cs, pseudo, sizeof(pseudo)); - 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)); } tcp->csum = csumfin(cs); } + MG_VERBOSE(("TCP %M -> %M fl %x len %u", mg_print_ip_port, ip_src, + mg_print_ip_port, ip_dst, tcp->flags, len)); return ether_output(ifp, PDIFF(ifp->tx.buf, tcp + 1) + len); } @@ -1083,11 +1088,11 @@ static size_t tx_tcp_ctrlresp(struct mg_tcpip_if *ifp, struct pkt *pkt, memset(&ips, 0, sizeof(ips)); memset(&ipd, 0, sizeof(ipd)); if (pkt->ip != NULL) { - ips.ip4 = pkt->ip->dst; - ipd.ip4 = pkt->ip->src; + ips.addr.ip4 = pkt->ip->dst; + ipd.addr.ip4 = pkt->ip->src; } else { - ips.ip6[0] = pkt->ip6->dst[0], ips.ip6[1] = pkt->ip6->dst[1]; - ipd.ip6[0] = pkt->ip6->src[0], ipd.ip6[1] = pkt->ip6->src[1]; + ips.addr.ip6[0] = pkt->ip6->dst[0], ips.addr.ip6[1] = pkt->ip6->dst[1]; + ipd.addr.ip6[0] = pkt->ip6->src[0], ipd.addr.ip6[1] = pkt->ip6->src[1]; ips.is_ip6 = true; ipd.is_ip6 = true; } @@ -1117,16 +1122,16 @@ static struct mg_connection *accept_conn(struct mg_connection *lsn, s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq); #if MG_ENABLE_IPV6 if (lsn->loc.is_ip6) { - c->rem.ip6[0] = pkt->ip6->src[0], c->rem.ip6[1] = pkt->ip6->src[1], - c->rem.is_ip6 = true; - c->loc.ip6[0] = c->mgr->ifp->ip6[0], c->loc.ip6[1] = c->mgr->ifp->ip6[1], - c->loc.is_ip6 = true; + c->rem.addr.ip6[0] = pkt->ip6->src[0], + c->rem.addr.ip6[1] = pkt->ip6->src[1], c->rem.is_ip6 = true; + c->loc.addr.ip6[0] = c->mgr->ifp->ip6[0], + c->loc.addr.ip6[1] = c->mgr->ifp->ip6[1], c->loc.is_ip6 = true; // TODO(): compare lsn to link-local, or rem as link-local: use ll instead } else #endif { - c->rem.ip4 = pkt->ip->src; - c->loc.ip4 = c->mgr->ifp->ip; + c->rem.addr.ip4 = pkt->ip->src; + c->loc.addr.ip4 = c->mgr->ifp->ip; } c->rem.port = pkt->tcp->sport; c->loc.port = lsn->loc.port; @@ -1188,12 +1193,13 @@ static bool udp_send(struct mg_connection *c, const void *buf, size_t len) { memset(&ips, 0, sizeof(ips)); #if MG_ENABLE_IPV6 if (c->loc.is_ip6) { - ips.ip6[0] = ifp->ip6[0], ips.ip6[1] = ifp->ip6[1], ips.is_ip6 = true; + ips.addr.ip6[0] = ifp->ip6[0], ips.addr.ip6[1] = ifp->ip6[1], + ips.is_ip6 = true; // TODO(): detect link-local (c->rem) and use it } else #endif { - ips.ip4 = ifp->ip; + ips.addr.ip4 = ifp->ip; } ips.port = c->loc.port; return tx_udp(ifp, s->mac, &ips, &c->rem, buf, len); @@ -1931,12 +1937,12 @@ void mg_connect_resolved(struct mg_connection *c) { c->loc.port = mg_htons(ifp->eport++); #if MG_ENABLE_IPV6 if (c->rem.is_ip6) { - c->loc.ip6[0] = ifp->ip6[0], c->loc.ip6[1] = ifp->ip6[1], + c->loc.addr.ip6[0] = ifp->ip6[0], c->loc.addr.ip6[1] = ifp->ip6[1], c->loc.is_ip6 = true; } else #endif { - c->loc.ip4 = ifp->ip; + c->loc.addr.ip4 = ifp->ip; } MG_DEBUG(("%lu %M -> %M", c->id, mg_print_ip_port, &c->loc, mg_print_ip_port, &c->rem)); @@ -1945,21 +1951,21 @@ void mg_connect_resolved(struct mg_connection *c) { #if MG_ENABLE_IPV6 if (c->rem.is_ip6) { if (c->is_udp && - MG_IP6MATCH(c->rem.ip6, ip6_allnodes.u)) { // local broadcast + MG_IP6MATCH(c->rem.addr.ip6, ip6_allnodes.u)) { // local broadcast struct connstate *s = (struct connstate *) (c + 1); memcpy(s->mac, ip6mac_allnodes, sizeof(s->mac)); mac_resolved(c); - } else if (c->rem.ip6[0] == ifp->ip6[0] && // TODO(): HANDLE PREFIX *** - !MG_IP6MATCH(c->rem.ip6, + } else if (c->rem.addr.ip6[0] == ifp->ip6[0] && // TODO(): HANDLE PREFIX *** + !MG_IP6MATCH(c->rem.addr.ip6, ifp->gw6)) { // skip if gw (onstate6change -> NS) // If we're in the same LAN, fire a Neighbor Solicitation MG_DEBUG(("%lu NS lookup...", c->id)); - tx_ndp_ns(ifp, c->rem.ip6, ifp->mac); + tx_ndp_ns(ifp, c->rem.addr.ip6, ifp->mac); settmout(c, MIP_TTYPE_ARP); c->is_arplooking = 1; - } else if (c->is_udp && *((uint8_t *) c->rem.ip6) == 0xFF) { // multicast + } else if (c->is_udp && *((uint8_t *) c->rem.addr.ip6) == 0xFF) { // multicast struct connstate *s = (struct connstate *) (c + 1); - ip6_mcastmac(s->mac, c->rem.ip6); + ip6_mcastmac(s->mac, c->rem.addr.ip6); mac_resolved(c); } else if (ifp->gw6_ready) { struct connstate *s = (struct connstate *) (c + 1); @@ -1971,7 +1977,7 @@ void mg_connect_resolved(struct mg_connection *c) { } else #endif { - uint32_t rem_ip = c->rem.ip4; + uint32_t rem_ip = c->rem.addr.ip4; if (c->is_udp && (rem_ip == 0xffffffff || rem_ip == (ifp->ip | ~ifp->mask))) { struct connstate *s = (struct connstate *) (c + 1); diff --git a/src/printf.c b/src/printf.c index fb6482af..57f5a957 100644 --- a/src/printf.c +++ b/src/printf.c @@ -38,8 +38,10 @@ void mg_pfn_iobuf(char ch, void *param) { } size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap) { - struct mg_iobuf io = {(uint8_t *) buf, len, 0, 0}; - size_t n = mg_vxprintf(mg_putchar_iobuf_static, &io, fmt, ap); + struct mg_iobuf io = {0, 0, 0, 0}; + size_t n; + io.buf = (uint8_t *) buf, io.size = len; + n = mg_vxprintf(mg_putchar_iobuf_static, &io, fmt, ap); if (n < len) buf[n] = '\0'; return n; } @@ -96,8 +98,8 @@ size_t mg_print_ip6(void (*out)(char, void *), void *arg, va_list *ap) { size_t mg_print_ip(void (*out)(char, void *), void *arg, va_list *ap) { struct mg_addr *addr = va_arg(*ap, struct mg_addr *); - if (addr->is_ip6) return print_ip6(out, arg, (uint16_t *) addr->ip); - return print_ip4(out, arg, (uint8_t *) &addr->ip); + if (addr->is_ip6) return print_ip6(out, arg, (uint16_t *) addr->addr.ip); + return print_ip4(out, arg, (uint8_t *) &addr->addr.ip); } size_t mg_print_ip_port(void (*out)(char, void *), void *arg, va_list *ap) { @@ -145,7 +147,8 @@ static size_t bcpy(void (*out)(char, void *), void *arg, uint8_t *buf, for (i = 0; i < len; i += 3) { uint8_t c1 = buf[i], c2 = i + 1 < len ? buf[i + 1] : 0, c3 = i + 2 < len ? buf[i + 2] : 0; - char tmp[4] = {t[c1 >> 2], t[(c1 & 3) << 4 | (c2 >> 4)], '=', '='}; + char tmp[4] = {0, 0, '=', '='}; + tmp[0] = t[c1 >> 2], tmp[1] = t[(c1 & 3) << 4 | (c2 >> 4)]; if (i + 1 < len) tmp[2] = t[(c2 & 15) << 2 | (c3 >> 6)]; if (i + 2 < len) tmp[3] = t[c3 & 63]; for (j = 0; j < sizeof(tmp) && tmp[j] != '\0'; j++) out(tmp[j], arg); diff --git a/src/sha256.c b/src/sha256.c index 62cfe2a6..aff320b5 100644 --- a/src/sha256.c +++ b/src/sha256.c @@ -180,6 +180,35 @@ void mg_hmac_sha256(uint8_t dst[32], uint8_t *key, size_t keysz, uint8_t *data, #define sig164(x) (rotr64(x, 19) ^ rotr64(x, 61) ^ ((x) >> 6)) static const uint64_t mg_sha256_k2[80] = { +#if defined(__DCC__) + 0x428a2f98d728ae22ull, 0x7137449123ef65cdull, 0xb5c0fbcfec4d3b2full, + 0xe9b5dba58189dbbcull, 0x3956c25bf348b538ull, 0x59f111f1b605d019ull, + 0x923f82a4af194f9bull, 0xab1c5ed5da6d8118ull, 0xd807aa98a3030242ull, + 0x12835b0145706fbeull, 0x243185be4ee4b28cull, 0x550c7dc3d5ffb4e2ull, + 0x72be5d74f27b896full, 0x80deb1fe3b1696b1ull, 0x9bdc06a725c71235ull, + 0xc19bf174cf692694ull, 0xe49b69c19ef14ad2ull, 0xefbe4786384f25e3ull, + 0x0fc19dc68b8cd5b5ull, 0x240ca1cc77ac9c65ull, 0x2de92c6f592b0275ull, + 0x4a7484aa6ea6e483ull, 0x5cb0a9dcbd41fbd4ull, 0x76f988da831153b5ull, + 0x983e5152ee66dfabull, 0xa831c66d2db43210ull, 0xb00327c898fb213full, + 0xbf597fc7beef0ee4ull, 0xc6e00bf33da88fc2ull, 0xd5a79147930aa725ull, + 0x06ca6351e003826full, 0x142929670a0e6e70ull, 0x27b70a8546d22ffcull, + 0x2e1b21385c26c926ull, 0x4d2c6dfc5ac42aedull, 0x53380d139d95b3dfull, + 0x650a73548baf63deull, 0x766a0abb3c77b2a8ull, 0x81c2c92e47edaee6ull, + 0x92722c851482353bull, 0xa2bfe8a14cf10364ull, 0xa81a664bbc423001ull, + 0xc24b8b70d0f89791ull, 0xc76c51a30654be30ull, 0xd192e819d6ef5218ull, + 0xd69906245565a910ull, 0xf40e35855771202aull, 0x106aa07032bbd1b8ull, + 0x19a4c116b8d2d0c8ull, 0x1e376c085141ab53ull, 0x2748774cdf8eeb99ull, + 0x34b0bcb5e19b48a8ull, 0x391c0cb3c5c95a63ull, 0x4ed8aa4ae3418acbull, + 0x5b9cca4f7763e373ull, 0x682e6ff3d6b2b8a3ull, 0x748f82ee5defb2fcull, + 0x78a5636f43172f60ull, 0x84c87814a1f0ab72ull, 0x8cc702081a6439ecull, + 0x90befffa23631e28ull, 0xa4506cebde82bde9ull, 0xbef9a3f7b2c67915ull, + 0xc67178f2e372532bull, 0xca273eceea26619cull, 0xd186b8c721c0c207ull, + 0xeada7dd6cde0eb1eull, 0xf57d4f7fee6ed178ull, 0x06f067aa72176fbaull, + 0x0a637dc5a2c898a6ull, 0x113f9804bef90daeull, 0x1b710b35131c471bull, + 0x28db77f523047d84ull, 0x32caab7b40c72493ull, 0x3c9ebe0a15c9bebcull, + 0x431d67c49c100d4cull, 0x4cc5d4becb3e42b6ull, 0x597f299cfc657e2aull, + 0x5fcb6fab3ad6faecull, 0x6c44198c4a475817ull +#else 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, @@ -206,7 +235,9 @@ static const uint64_t mg_sha256_k2[80] = { 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, - 0x5fcb6fab3ad6faec, 0x6c44198c4a475817}; + 0x5fcb6fab3ad6faec, 0x6c44198c4a475817 +#endif +}; static void mg_sha384_transform(mg_sha384_ctx *ctx, const uint8_t data[]) { uint64_t m[80]; @@ -257,6 +288,16 @@ void mg_sha384_init(mg_sha384_ctx *ctx) { ctx->datalen = 0; ctx->bitlen[0] = 0; ctx->bitlen[1] = 0; +#if defined(__DCC__) + ctx->state[0] = 0xcbbb9d5dc1059ed8ull; + ctx->state[1] = 0x629a292a367cd507ull; + ctx->state[2] = 0x9159015a3070dd17ull; + ctx->state[3] = 0x152fecd8f70e5939ull; + ctx->state[4] = 0x67332667ffc00b31ull; + ctx->state[5] = 0x8eb44a8768581511ull; + ctx->state[6] = 0xdb0c2e0d64f98fa7ull; + ctx->state[7] = 0x47b5481dbefa4fa4ull; +#else ctx->state[0] = 0xcbbb9d5dc1059ed8; ctx->state[1] = 0x629a292a367cd507; ctx->state[2] = 0x9159015a3070dd17; @@ -265,6 +306,7 @@ void mg_sha384_init(mg_sha384_ctx *ctx) { ctx->state[5] = 0x8eb44a8768581511; ctx->state[6] = 0xdb0c2e0d64f98fa7; ctx->state[7] = 0x47b5481dbefa4fa4; +#endif } void mg_sha384_update(mg_sha384_ctx *ctx, const uint8_t *data, size_t len) { diff --git a/src/sock.c b/src/sock.c index 26d8fd8c..6b2bd5f3 100644 --- a/src/sock.c +++ b/src/sock.c @@ -57,13 +57,13 @@ static socklen_t tousa(struct mg_addr *a, union usa *usa) { memset(usa, 0, sizeof(*usa)); usa->sin.sin_family = AF_INET; usa->sin.sin_port = a->port; - memcpy(&usa->sin.sin_addr, a->ip, sizeof(uint32_t)); + memcpy(&usa->sin.sin_addr, a->addr.ip, sizeof(uint32_t)); #if MG_ENABLE_IPV6 if (a->is_ip6) { usa->sin.sin_family = AF_INET6; usa->sin6.sin6_port = a->port; usa->sin6.sin6_scope_id = a->scope_id; - memcpy(&usa->sin6.sin6_addr, a->ip, sizeof(a->ip)); + memcpy(&usa->sin6.sin6_addr, a->addr.ip, sizeof(a->addr.ip)); len = sizeof(usa->sin6); } #endif @@ -73,10 +73,10 @@ static socklen_t tousa(struct mg_addr *a, union usa *usa) { static void tomgaddr(union usa *usa, struct mg_addr *a, bool is_ip6) { a->is_ip6 = is_ip6; a->port = usa->sin.sin_port; - memcpy(&a->ip, &usa->sin.sin_addr, sizeof(uint32_t)); + memcpy(&a->addr.ip, &usa->sin.sin_addr, sizeof(uint32_t)); #if MG_ENABLE_IPV6 if (is_ip6) { - memcpy(a->ip, &usa->sin6.sin6_addr, sizeof(a->ip)); + memcpy(a->addr.ip, &usa->sin6.sin6_addr, sizeof(a->addr.ip)); a->port = usa->sin6.sin6_port; a->scope_id = (uint8_t) usa->sin6.sin6_scope_id; } diff --git a/src/str.c b/src/str.c index 75e5cd38..db91fa6a 100644 --- a/src/str.c +++ b/src/str.c @@ -2,12 +2,14 @@ #include "util.h" struct mg_str mg_str_s(const char *s) { - struct mg_str str = {(char *) s, s == NULL ? 0 : strlen(s)}; + struct mg_str str; + str.buf = (char *) s, str.len = (s == NULL) ? 0 : strlen(s); return str; } struct mg_str mg_str_n(const char *s, size_t n) { - struct mg_str str = {(char *) s, n}; + struct mg_str str; + str.buf = (char *) s, str.len = n; return str; } diff --git a/src/tls_builtin.c b/src/tls_builtin.c index f74ac731..431fa27f 100644 --- a/src/tls_builtin.c +++ b/src/tls_builtin.c @@ -1215,7 +1215,7 @@ static int mg_tls_verify_cert_san(const uint8_t *der, size_t dersz, while (mg_der_next(&field, &name) > 0) { if (name.type == 0x87 && name.len == 4) { // this is an IPv4 address MG_DEBUG(("Found SAN, IP: %M", mg_print_ip4, name.value)); - if (!server_ip->is_ip6 && *((uint32_t *) name.value) == server_ip->ip4) + if (!server_ip->is_ip6 && *((uint32_t *) name.value) == server_ip->addr.ip4) return 1; // and matches the one we're connected to } else { // this is a text SAN MG_DEBUG(("Found SAN, (%u): %.*s", name.type, name.len, name.value)); diff --git a/src/util.c b/src/util.c index f5b6b6a3..a99d7efa 100644 --- a/src/util.c +++ b/src/util.c @@ -120,7 +120,7 @@ int mg_check_ip_acl(struct mg_str acl, struct mg_addr *remote_ip) { if (remote_ip->is_ip6) { return -1; // TODO(): handle IPv6 ACL and addresses } else { // IPv4 - memcpy((void *) &remote_ip4, remote_ip->ip, sizeof(remote_ip4)); + memcpy((void *) &remote_ip4, remote_ip->addr.ip, sizeof(remote_ip4)); while (mg_span(acl, &entry, &acl, ',')) { uint32_t net, mask; if (entry.buf[0] != '+' && entry.buf[0] != '-') return -1; @@ -134,7 +134,7 @@ int mg_check_ip_acl(struct mg_str acl, struct mg_addr *remote_ip) { bool mg_path_is_sane(const struct mg_str path) { const char *s = path.buf; size_t n = path.len; - if (path.buf[0] == '~') return false; // Starts with ~ + if (path.buf[0] == '~') return false; // Starts with ~ if (path.buf[0] == '.' && path.buf[1] == '.') return false; // Starts with .. for (; s[0] != '\0' && n > 0; s++, n--) { if ((s[0] == '/' || s[0] == '\\') && n >= 2) { // Subdir? @@ -213,7 +213,6 @@ void mg_delayms(unsigned int ms) { while (mg_millis() < to) (void) 0; } - #if MG_ENABLE_CUSTOM_CALLOC #else void *mg_calloc(size_t count, size_t size) { diff --git a/src/ws.c b/src/ws.c index cc5063ba..c4ab6b9a 100644 --- a/src/ws.c +++ b/src/ws.c @@ -173,9 +173,13 @@ static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data) { while (ws_process(c->recv.buf + ofs, c->recv.len - ofs, &msg) > 0) { char *s = (char *) c->recv.buf + ofs + msg.header_len; - struct mg_ws_message m = {{s, msg.data_len}, msg.flags}; - size_t len = msg.header_len + msg.data_len; - uint8_t final = msg.flags & 128, op = msg.flags & 15; + struct mg_ws_message m; + size_t len; + uint8_t final, op; + m.data.buf = s, m.data.len = msg.data_len, m.flags = msg.flags; + len = msg.header_len + msg.data_len; + final = msg.flags & 128; + op = msg.flags & 15; // MG_VERBOSE ("fin %d op %d len %d [%.*s]", final, op, // (int) m.data.len, (int) m.data.len, m.data.buf)); switch (op) { diff --git a/test/unit_test.c b/test/unit_test.c index bc5267ad..85c75082 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -1496,7 +1496,7 @@ static void f3(struct mg_connection *c, int ev, void *ev_data) { // MG_INFO(("%d", ev)); if (ev == MG_EV_CONNECT) { // c->is_hexdumping = 1; - ASSERT((c->loc.ip[0] != 0)); // Make sure that c->loc address is populated + ASSERT((c->loc.addr.ip[0] != 0)); // Make sure that c->loc address is populated mg_printf(c, "GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n", c->rem.is_ip6 ? "" : "/robots.txt", c->rem.is_ip6 ? "ipv6.google.com" : "cesanta.com"); @@ -2478,7 +2478,7 @@ static void test_str(void) { char buf[100]; struct mg_addr a; uint32_t addr = mg_htonl(0x2000001); - memcpy(a.ip, &addr, sizeof(uint32_t)); + memcpy(a.addr.ip, &addr, sizeof(uint32_t)); a.port = mg_htons(3); a.is_ip6 = false; @@ -2488,8 +2488,8 @@ static void test_str(void) { 11); ASSERT(strcmp(buf, "2.0.0.1:3 7") == 0); - memset(a.ip, 0, sizeof(a.ip)); - a.ip[0] = 1, a.ip[1] = 100, a.ip[2] = 33; + memset(a.addr.ip, 0, sizeof(a.addr.ip)); + a.addr.ip[0] = 1, a.addr.ip[1] = 100, a.addr.ip[2] = 33; a.is_ip6 = true; ASSERT(mg_snprintf(buf, sizeof(buf), "%M %d", mg_print_ip, &a, 7) == 24); ASSERT(strcmp(buf, "[164:2100:0:0:0:0:0:0] 7") == 0); @@ -2636,7 +2636,7 @@ static void test_util(void) { ASSERT(mg_aton(mg_str("0.0.0.-1"), &a) == false); ASSERT(mg_aton(mg_str("127.0.0.1"), &a) == true); ASSERT(a.is_ip6 == false); - memcpy(&ipv4, a.ip, sizeof(ipv4)); + memcpy(&ipv4, &a.addr.ip4, sizeof(ipv4)); ASSERT(ipv4 == mg_htonl(0x7f000001)); ASSERT(mg_ntohl(ipv4) == 0x7f000001); MG_STORE_BE32(&ipv4, 0x5678abcd); @@ -2667,48 +2667,48 @@ static void test_util(void) { ((uint8_t *) &ipv3)[6] == 0x9e && ((uint8_t *) &ipv3)[7] == 0xf0); ASSERT(MG_LOAD_BE64(&ipv3) == 0x5678abcd12349ef0); - memset(a.ip, 0xa5, sizeof(a.ip)); + memset(a.addr.ip, 0xa5, sizeof(a.addr.ip)), a.is_ip6 = false; ASSERT(mg_aton(mg_str("1:2:3:4:5:6:7:8"), &a) == true); ASSERT(a.is_ip6 == true); e = "\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08"; - ASSERT(memcmp(a.ip, e, sizeof(a.ip)) == 0); + ASSERT(memcmp(&a.addr.ip6, e, sizeof(a.addr.ip6)) == 0); - memset(a.ip, 0xa5, sizeof(a.ip)); + memset(a.addr.ip, 0xa5, sizeof(a.addr.ip)), a.is_ip6 = false; ASSERT(mg_aton(mg_str("1:2::3"), &a) == true); ASSERT(a.is_ip6 == true); e = "\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"; - ASSERT(memcmp(a.ip, e, sizeof(a.ip)) == 0); + ASSERT(memcmp(&a.addr.ip6, e, sizeof(a.addr.ip6)) == 0); - memset(a.ip, 0xaa, sizeof(a.ip)); + memset(a.addr.ip, 0xaa, sizeof(a.addr.ip)), a.is_ip6 = false; ASSERT(mg_aton(mg_str("1::1"), &a) == true); ASSERT(a.is_ip6 == true); e = "\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"; - ASSERT(memcmp(a.ip, e, sizeof(a.ip)) == 0); + ASSERT(memcmp(&a.addr.ip6, e, sizeof(a.addr.ip6)) == 0); - memset(a.ip, 0xaa, sizeof(a.ip)); + memset(a.addr.ip, 0xaa, sizeof(a.addr.ip)), a.is_ip6 = false; ASSERT(mg_aton(mg_str("::fFff:1.2.3.4"), &a) == true); ASSERT(a.is_ip6 == true); e = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x01\x02\x03\x04"; - ASSERT(memcmp(a.ip, e, sizeof(a.ip)) == 0); + ASSERT(memcmp(&a.addr.ip6, e, sizeof(a.addr.ip6)) == 0); - memset(a.ip, 0xaa, sizeof(a.ip)); + memset(a.addr.ip, 0xaa, sizeof(a.addr.ip)), a.is_ip6 = false; ASSERT(mg_aton(mg_str("::1"), &a) == true); ASSERT(a.is_ip6 == true); ASSERT(a.scope_id == 0); e = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"; - ASSERT(memcmp(a.ip, e, sizeof(a.ip)) == 0); + ASSERT(memcmp(&a.addr.ip6, e, sizeof(a.addr.ip6)) == 0); - memset(a.ip, 0xaa, sizeof(a.ip)); + memset(a.addr.ip, 0xaa, sizeof(a.addr.ip)), a.is_ip6 = false; ASSERT(mg_aton(mg_str("1::"), &a) == true); ASSERT(a.is_ip6 == true); e = "\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; - ASSERT(memcmp(a.ip, e, sizeof(a.ip)) == 0); + ASSERT(memcmp(&a.addr.ip6, e, sizeof(a.addr.ip6)) == 0); - memset(a.ip, 0xaa, sizeof(a.ip)); + memset(a.addr.ip, 0xaa, sizeof(a.addr.ip)), a.is_ip6 = false; ASSERT(mg_aton(mg_str("2001:4860:4860::8888"), &a) == true); ASSERT(a.is_ip6 == true); e = "\x20\x01\x48\x60\x48\x60\x00\x00\x00\x00\x00\x00\x00\x00\x88\x88"; - ASSERT(memcmp(a.ip, e, sizeof(a.ip)) == 0); + ASSERT(memcmp(&a.addr.ip6, e, sizeof(a.addr.ip6)) == 0); ASSERT(mg_url_decode("a=%", 3, buf, sizeof(buf), 0) < 0); ASSERT(mg_url_decode("&&&a=%", 6, buf, sizeof(buf), 0) < 0);