From 074ef5197bdd78d46e7ae027c2a1f0199adab666 Mon Sep 17 00:00:00 2001 From: Sergey Lyubka Date: Tue, 24 Jun 2025 09:46:38 +0100 Subject: [PATCH 1/2] Introduce mg_calloc --- mongoose.c | 234 +++++++++++++++++++------------------------- mongoose.h | 87 ++++++++-------- src/arch_freertos.h | 9 +- src/config.h | 4 + src/dns.c | 4 +- src/fs.c | 12 +-- src/fs_fat.c | 4 +- src/fs_packed.c | 4 +- src/fs_posix.c | 6 +- src/iobuf.c | 9 +- src/json.c | 8 +- src/net.c | 12 +-- src/net_builtin.c | 8 +- src/ota_mcxn.c | 2 +- src/ota_picosdk.c | 2 +- src/rpc.c | 6 +- src/ssi.c | 6 +- src/str.c | 2 +- src/timer.c | 2 +- src/timer.h | 2 +- src/tls_builtin.c | 59 ++++++----- src/tls_mbed.c | 10 +- src/tls_openssl.c | 6 +- src/tls_rsa.c | 60 ++---------- src/util.c | 12 +++ src/util.h | 2 + 26 files changed, 259 insertions(+), 313 deletions(-) diff --git a/mongoose.c b/mongoose.c index 783fb50d..223a4e4f 100644 --- a/mongoose.c +++ b/mongoose.c @@ -139,7 +139,7 @@ static void mg_sendnsreq(struct mg_connection *, struct mg_str *, int, static void mg_dns_free(struct dns_data **head, struct dns_data *d) { LIST_DELETE(struct dns_data, head, d); - free(d); + mg_free(d); } void mg_resolve_cancel(struct mg_connection *c) { @@ -367,7 +367,7 @@ static void mg_sendnsreq(struct mg_connection *c, struct mg_str *name, int ms, } if (dnsc->c == NULL) { mg_error(c, "resolver"); - } else if ((d = (struct dns_data *) calloc(1, sizeof(*d))) == NULL) { + } else if ((d = (struct dns_data *) mg_calloc(1, sizeof(*d))) == NULL) { mg_error(c, "resolve OOM"); } else { struct dns_data *reqs = (struct dns_data *) c->mgr->active_dns_requests; @@ -822,12 +822,12 @@ size_t mg_vxprintf(void (*out)(char, void *), void *param, const char *fmt, struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags) { - struct mg_fd *fd = (struct mg_fd *) calloc(1, sizeof(*fd)); + struct mg_fd *fd = (struct mg_fd *) mg_calloc(1, sizeof(*fd)); if (fd != NULL) { fd->fd = fs->op(path, flags); fd->fs = fs; if (fd->fd == NULL) { - free(fd); + mg_free(fd); fd = NULL; } } @@ -837,7 +837,7 @@ struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags) { void mg_fs_close(struct mg_fd *fd) { if (fd != NULL) { fd->fs->cl(fd->fd); - free(fd); + mg_free(fd); } } @@ -846,10 +846,10 @@ struct mg_str mg_file_read(struct mg_fs *fs, const char *path) { void *fp; fs->st(path, &result.len, NULL); if ((fp = fs->op(path, MG_FS_READ)) != NULL) { - result.buf = (char *) calloc(1, result.len + 1); + result.buf = (char *) mg_calloc(1, result.len + 1); if (result.buf != NULL && fs->rd(fp, (void *) result.buf, result.len) != result.len) { - free((void *) result.buf); + mg_free((void *) result.buf); result.buf = NULL; } fs->cl(fp); @@ -885,7 +885,7 @@ bool mg_file_printf(struct mg_fs *fs, const char *path, const char *fmt, ...) { data = mg_vmprintf(fmt, &ap); va_end(ap); result = mg_file_write(fs, path, data, strlen(data)); - free(data); + mg_free(data); return result; } @@ -988,7 +988,7 @@ static void *ff_open(const char *path, int flags) { if (flags & MG_FS_WRITE) mode |= FA_WRITE | FA_OPEN_ALWAYS | FA_OPEN_APPEND; if (f_open(&f, path, mode) == 0) { FIL *fp; - if ((fp = calloc(1, sizeof(*fp))) != NULL) { + if ((fp = mg_calloc(1, sizeof(*fp))) != NULL) { memcpy(fp, &f, sizeof(*fp)); return fp; } @@ -999,7 +999,7 @@ static void *ff_open(const char *path, int flags) { static void ff_close(void *fp) { if (fp != NULL) { f_close((FIL *) fp); - free(fp); + mg_free(fp); } } @@ -1118,7 +1118,7 @@ static void *packed_open(const char *path, int flags) { struct packed_file *fp = NULL; if (data == NULL) return NULL; if (flags & MG_FS_WRITE) return NULL; - if ((fp = (struct packed_file *) calloc(1, sizeof(*fp))) != NULL) { + if ((fp = (struct packed_file *) mg_calloc(1, sizeof(*fp))) != NULL) { fp->size = size; fp->data = data; } @@ -1126,7 +1126,7 @@ static void *packed_open(const char *path, int flags) { } static void packed_close(void *fp) { - if (fp != NULL) free(fp); + if (fp != NULL) mg_free(fp); } static size_t packed_read(void *fd, void *buf, size_t len) { @@ -1272,7 +1272,7 @@ DIR *opendir(const char *name) { if (name == NULL) { SetLastError(ERROR_BAD_ARGUMENTS); - } else if ((d = (DIR *) calloc(1, sizeof(*d))) == NULL) { + } else if ((d = (DIR *) mg_calloc(1, sizeof(*d))) == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); } else { to_wchar(name, wpath, sizeof(wpath) / sizeof(wpath[0])); @@ -1282,7 +1282,7 @@ DIR *opendir(const char *name) { d->handle = FindFirstFileW(wpath, &d->info); d->result.d_name[0] = '\0'; } else { - free(d); + mg_free(d); d = NULL; } } @@ -1294,7 +1294,7 @@ int closedir(DIR *d) { if (d != NULL) { if (d->handle != INVALID_HANDLE_VALUE) result = FindClose(d->handle) ? 0 : -1; - free(d); + mg_free(d); } else { result = -1; SetLastError(ERROR_BAD_ARGUMENTS); @@ -2616,18 +2616,17 @@ int mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) { new_size = roundup(new_size, io->align); if (new_size == 0) { mg_bzero(io->buf, io->size); - free(io->buf); + mg_free(io->buf); io->buf = NULL; io->len = io->size = 0; } else if (new_size != io->size) { - // NOTE(lsm): do not use realloc here. Use calloc/free only, to ease the - // porting to some obscure platforms like FreeRTOS - void *p = calloc(1, new_size); + // NOTE(lsm): do not use realloc here. Use mg_calloc/mg_free only + void *p = mg_calloc(1, new_size); if (p != NULL) { size_t len = new_size < io->len ? new_size : io->len; if (len > 0 && io->buf != NULL) memmove(p, io->buf, len); mg_bzero(io->buf, io->size); - free(io->buf); + mg_free(io->buf); io->buf = (unsigned char *) p; io->size = new_size; } else { @@ -2995,10 +2994,10 @@ char *mg_json_get_str(struct mg_str json, const char *path) { char *result = NULL; int len = 0, off = mg_json_get(json, path, &len); if (off >= 0 && len > 1 && json.buf[off] == '"') { - if ((result = (char *) calloc(1, (size_t) len)) != NULL && + if ((result = (char *) mg_calloc(1, (size_t) len)) != NULL && !mg_json_unescape(mg_str_n(json.buf + off + 1, (size_t) (len - 2)), result, (size_t) len)) { - free(result); + mg_free(result); result = NULL; } } @@ -3009,7 +3008,7 @@ char *mg_json_get_b64(struct mg_str json, const char *path, int *slen) { char *result = NULL; int len = 0, off = mg_json_get(json, path, &len); if (off >= 0 && json.buf[off] == '"' && len > 1 && - (result = (char *) calloc(1, (size_t) len)) != NULL) { + (result = (char *) mg_calloc(1, (size_t) len)) != NULL) { size_t k = mg_base64_decode(json.buf + off + 1, (size_t) (len - 2), result, (size_t) len); if (slen != NULL) *slen = (int) k; @@ -3021,7 +3020,7 @@ char *mg_json_get_hex(struct mg_str json, const char *path, int *slen) { char *result = NULL; int len = 0, off = mg_json_get(json, path, &len); if (off >= 0 && json.buf[off] == '"' && len > 1 && - (result = (char *) calloc(1, (size_t) len / 2)) != NULL) { + (result = (char *) mg_calloc(1, (size_t) len / 2)) != NULL) { int i; for (i = 0; i < len - 2; i += 2) { mg_str_to_num(mg_str_n(json.buf + off + 1 + i, 2), 16, &result[i >> 1], @@ -4004,7 +4003,7 @@ bool mg_aton(struct mg_str str, struct mg_addr *addr) { struct mg_connection *mg_alloc_conn(struct mg_mgr *mgr) { struct mg_connection *c = - (struct mg_connection *) calloc(1, sizeof(*c) + mgr->extraconnsize); + (struct mg_connection *) mg_calloc(1, sizeof(*c) + mgr->extraconnsize); if (c != NULL) { c->mgr = mgr; c->send.align = c->recv.align = c->rtls.align = MG_IO_SIZE; @@ -4031,7 +4030,7 @@ void mg_close_conn(struct mg_connection *c) { mg_iobuf_free(&c->send); mg_iobuf_free(&c->rtls); mg_bzero((unsigned char *) c, sizeof(*c)); - free(c); + mg_free(c); } struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *url, @@ -4064,7 +4063,7 @@ struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url, } else if (!mg_open_listener(c, url)) { MG_ERROR(("Failed: %s", url)); MG_PROF_FREE(c); - free(c); + mg_free(c); c = NULL; } else { c->is_listening = 1; @@ -4095,9 +4094,9 @@ struct mg_connection *mg_wrapfd(struct mg_mgr *mgr, int fd, struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds, unsigned flags, void (*fn)(void *), void *arg) { - struct mg_timer *t = (struct mg_timer *) calloc(1, sizeof(*t)); + struct mg_timer *t = (struct mg_timer *) mg_calloc(1, sizeof(*t)); if (t != NULL) { - flags |= MG_TIMER_AUTODELETE; // We have calloc-ed it, so autodelete + flags |= MG_TIMER_AUTODELETE; // We have mg_calloc-ed it, so autodelete mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg); } return t; @@ -4114,7 +4113,7 @@ long mg_io_recv(struct mg_connection *c, void *buf, size_t len) { void mg_mgr_free(struct mg_mgr *mgr) { struct mg_connection *c; struct mg_timer *tmp, *t = mgr->timers; - while (t != NULL) tmp = t->next, free(t), t = tmp; + while (t != NULL) tmp = t->next, mg_free(t), t = tmp; mgr->timers = NULL; // Important. Next call to poll won't touch timers for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1; mg_mgr_poll(mgr, 0); @@ -5247,10 +5246,10 @@ void mg_tcpip_init(struct mg_mgr *mgr, struct mg_tcpip_if *ifp) { MG_ERROR(("driver init failed")); } else { size_t framesize = 1540; - ifp->tx.buf = (char *) calloc(1, framesize), ifp->tx.len = framesize; + ifp->tx.buf = (char *) mg_calloc(1, framesize), ifp->tx.len = framesize; if (ifp->recv_queue.size == 0) ifp->recv_queue.size = ifp->driver->rx ? framesize : 8192; - ifp->recv_queue.buf = (char *) calloc(1, ifp->recv_queue.size); + ifp->recv_queue.buf = (char *) mg_calloc(1, ifp->recv_queue.size); ifp->timer_1000ms = mg_millis(); mgr->ifp = ifp; ifp->mgr = mgr; @@ -5266,8 +5265,8 @@ void mg_tcpip_init(struct mg_mgr *mgr, struct mg_tcpip_if *ifp) { } void mg_tcpip_free(struct mg_tcpip_if *ifp) { - free(ifp->recv_queue.buf); - free(ifp->tx.buf); + mg_free(ifp->recv_queue.buf); + mg_free(ifp->tx.buf); } static void send_syn(struct mg_connection *c) { @@ -6748,7 +6747,7 @@ fwxit: // try to swap (honor dual image), otherwise just overwrite MG_IRAM static void single_bank_swap(char *p1, char *p2, size_t s, size_t ss) { - char *tmp = malloc(ss); + char *tmp = mg_calloc(1, ss); // no stdlib calls here for (size_t ofs = 0; ofs < s; ofs += ss) { if (tmp != NULL) @@ -6911,7 +6910,7 @@ static bool __no_inline_not_in_flash_func(mg_picosdk_write)(void *addr, static void __no_inline_not_in_flash_func(single_bank_swap)(char *p1, char *p2, size_t s, size_t ss) { - char *tmp = malloc(ss); + char *tmp = mg_calloc(1, ss); if (tmp == NULL) return; #if PICO_RP2040 uint32_t xip[256 / sizeof(uint32_t)]; @@ -7867,7 +7866,7 @@ void mg_queue_del(struct mg_queue *q, size_t len) { void mg_rpc_add(struct mg_rpc **head, struct mg_str method, void (*fn)(struct mg_rpc_req *), void *fn_data) { - struct mg_rpc *rpc = (struct mg_rpc *) calloc(1, sizeof(*rpc)); + struct mg_rpc *rpc = (struct mg_rpc *) mg_calloc(1, sizeof(*rpc)); if (rpc != NULL) { rpc->method = mg_strdup(method); rpc->fn = fn; @@ -7881,8 +7880,8 @@ void mg_rpc_del(struct mg_rpc **head, void (*fn)(struct mg_rpc_req *)) { while ((r = *head) != NULL) { if (r->fn == fn || fn == NULL) { *head = r->next; - free((void *) r->method.buf); - free(r); + mg_free((void *) r->method.buf); + mg_free(r); } else { head = &(*head)->next; } @@ -9411,7 +9410,7 @@ static char *mg_ssi(const char *path, const char *root, int depth) { if (depth < MG_MAX_SSI_DEPTH && (data = mg_ssi(tmp, root, depth + 1)) != NULL) { mg_iobuf_add(&b, b.len, data, strlen(data)); - free(data); + mg_free(data); } else { MG_ERROR(("%s: file=%s error or too deep", path, arg)); } @@ -9421,7 +9420,7 @@ static char *mg_ssi(const char *path, const char *root, int depth) { if (depth < MG_MAX_SSI_DEPTH && (data = mg_ssi(tmp, root, depth + 1)) != NULL) { mg_iobuf_add(&b, b.len, data, strlen(data)); - free(data); + mg_free(data); } else { MG_ERROR(("%s: virtual=%s error or too deep", path, arg)); } @@ -9467,7 +9466,7 @@ void mg_http_serve_ssi(struct mg_connection *c, const char *root, const char *headers = "Content-Type: text/html; charset=utf-8\r\n"; char *data = mg_ssi(fullpath, root, 0); mg_http_reply(c, 200, headers, "%s", data == NULL ? "" : data); - free(data); + mg_free(data); } #else void mg_http_serve_ssi(struct mg_connection *c, const char *root, @@ -9508,7 +9507,7 @@ int mg_casecmp(const char *s1, const char *s2) { struct mg_str mg_strdup(const struct mg_str s) { struct mg_str r = {NULL, 0}; if (s.len > 0 && s.buf != NULL) { - char *sc = (char *) calloc(1, s.len + 1); + char *sc = (char *) mg_calloc(1, s.len + 1); if (sc != NULL) { memcpy(sc, s.buf, s.len); sc[s.len] = '\0'; @@ -9707,7 +9706,7 @@ void mg_timer_poll(struct mg_timer **head, uint64_t now_ms) { // If this timer is not repeating and marked AUTODELETE, remove it if (!(t->flags & MG_TIMER_REPEAT) && (t->flags & MG_TIMER_AUTODELETE)) { mg_timer_free(head, t); - free(t); + mg_free(t); } } } @@ -10880,13 +10879,13 @@ int mg_aes_gcm_decrypt(unsigned char *output, const unsigned char *input, // refer to RFC8446#A.1 enum mg_tls_hs_state { // Client state machine: - MG_TLS_STATE_CLIENT_START, // Send ClientHello - MG_TLS_STATE_CLIENT_WAIT_SH, // Wait for ServerHello - MG_TLS_STATE_CLIENT_WAIT_EE, // Wait for EncryptedExtensions - MG_TLS_STATE_CLIENT_WAIT_CERT, // Wait for Certificate - MG_TLS_STATE_CLIENT_WAIT_CV, // Wait for CertificateVerify - MG_TLS_STATE_CLIENT_WAIT_FINISH, // Wait for Finish - MG_TLS_STATE_CLIENT_CONNECTED, // Done + MG_TLS_STATE_CLIENT_START, // Send ClientHello + MG_TLS_STATE_CLIENT_WAIT_SH, // Wait for ServerHello + MG_TLS_STATE_CLIENT_WAIT_EE, // Wait for EncryptedExtensions + MG_TLS_STATE_CLIENT_WAIT_CERT, // Wait for Certificate + MG_TLS_STATE_CLIENT_WAIT_CV, // Wait for CertificateVerify + MG_TLS_STATE_CLIENT_WAIT_FINISH, // Wait for Finish + MG_TLS_STATE_CLIENT_CONNECTED, // Done // Server state machine: MG_TLS_STATE_SERVER_START, // Wait for ClientHello @@ -11270,7 +11269,7 @@ static void mg_tls_encrypt(struct mg_connection *c, const uint8_t *msg, nonce[8] ^= (uint8_t) ((seq >> 24) & 255U); nonce[9] ^= (uint8_t) ((seq >> 16) & 255U); nonce[10] ^= (uint8_t) ((seq >> 8) & 255U); - nonce[11] ^= (uint8_t) ((seq) &255U); + nonce[11] ^= (uint8_t) ((seq) & 255U); mg_iobuf_add(wio, wio->len, hdr, sizeof(hdr)); mg_iobuf_resize(wio, wio->len + encsz); @@ -11282,7 +11281,7 @@ static void mg_tls_encrypt(struct mg_connection *c, const uint8_t *msg, (void) tag; // tag is only used in aes gcm { size_t maxlen = MG_IO_SIZE > 16384 ? 16384 : MG_IO_SIZE; - uint8_t *enc = (uint8_t *) calloc(1, maxlen + 256 + 1); + uint8_t *enc = (uint8_t *) mg_calloc(1, maxlen + 256 + 1); if (enc == NULL) { mg_error(c, "TLS OOM"); return; @@ -11291,7 +11290,7 @@ static void mg_tls_encrypt(struct mg_connection *c, const uint8_t *msg, sizeof(associated_data), outmsg, msgsz + 1); memmove(outmsg, enc, n); - free(enc); + mg_free(enc); } } #else @@ -11349,10 +11348,10 @@ static int mg_tls_recv_record(struct mg_connection *c) { nonce[8] ^= (uint8_t) ((seq >> 24) & 255U); nonce[9] ^= (uint8_t) ((seq >> 16) & 255U); nonce[10] ^= (uint8_t) ((seq >> 8) & 255U); - nonce[11] ^= (uint8_t) ((seq) &255U); + nonce[11] ^= (uint8_t) ((seq) & 255U); #if CHACHA20 { - uint8_t *dec = (uint8_t *) calloc(1, msgsz); + uint8_t *dec = (uint8_t *) mg_calloc(1, msgsz); size_t n; if (dec == NULL) { mg_error(c, "TLS OOM"); @@ -11360,7 +11359,7 @@ static int mg_tls_recv_record(struct mg_connection *c) { } n = mg_chacha20_poly1305_decrypt(dec, key, nonce, msg, msgsz); memmove(msg, dec, n); - free(dec); + mg_free(dec); } #else mg_gcm_initialize(); @@ -11533,7 +11532,7 @@ static void mg_tls_server_send_cert(struct mg_connection *c) { int send_ca = !c->is_client && tls->ca_der.len > 0; // server DER certificate + CA (optional) size_t n = tls->cert_der.len + (send_ca ? tls->ca_der.len + 5 : 0); - uint8_t *cert = (uint8_t *) calloc(1, 13 + n); + uint8_t *cert = (uint8_t *) mg_calloc(1, 13 + n); if (cert == NULL) { mg_error(c, "tls cert oom"); return; @@ -11556,7 +11555,7 @@ static void mg_tls_server_send_cert(struct mg_connection *c) { } mg_sha256_update(&tls->sha256, cert, 13 + n); mg_tls_encrypt(c, cert, 13 + n, MG_TLS_HANDSHAKE); - free(cert); + mg_free(cert); } // type adapter between uECC hash context and our sha256 implementation @@ -12369,9 +12368,7 @@ static void mg_tls_client_handshake(struct mg_connection *c) { c->is_tls_hs = 0; mg_call(c, MG_EV_TLS_HS, NULL); break; - default: - mg_error(c, "unexpected client state: %d", tls->state); - break; + default: mg_error(c, "unexpected client state: %d", tls->state); break; } } @@ -12398,9 +12395,7 @@ static void mg_tls_server_handshake(struct mg_connection *c) { tls->state = MG_TLS_STATE_SERVER_CONNECTED; c->is_tls_hs = 0; return; - default: - mg_error(c, "unexpected server state: %d", tls->state); - break; + default: mg_error(c, "unexpected server state: %d", tls->state); break; } } @@ -12416,8 +12411,8 @@ void mg_tls_handshake(struct mg_connection *c) { while (tls->send.len > 0 && (n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) { mg_iobuf_del(&tls->send, 0, (size_t) n); - } // if last chunk fails to be sent, it will be sent with first app data, - // otherwise, it needs to be flushed + } // if last chunk fails to be sent, it will be sent with first app data, + // otherwise, it needs to be flushed } static int mg_parse_pem(const struct mg_str pem, const struct mg_str label, @@ -12433,7 +12428,7 @@ static int mg_parse_pem(const struct mg_str pem, const struct mg_str label, if (mg_strcmp(caps[1], label) != 0 || mg_strcmp(caps[3], label) != 0) { return -1; // bad label } - if ((s = (char *) calloc(1, caps[2].len)) == NULL) { + if ((s = (char *) mg_calloc(1, caps[2].len)) == NULL) { return -1; } @@ -12445,7 +12440,7 @@ static int mg_parse_pem(const struct mg_str pem, const struct mg_str label, } m = mg_base64_decode(s, n, s, n); if (m == 0) { - free(s); + mg_free(s); return -1; } der->buf = s; @@ -12455,7 +12450,8 @@ static int mg_parse_pem(const struct mg_str pem, const struct mg_str label, void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { struct mg_str key; - struct tls_data *tls = (struct tls_data *) calloc(1, sizeof(struct tls_data)); + struct tls_data *tls = + (struct tls_data *) mg_calloc(1, sizeof(struct tls_data)); if (tls == NULL) { mg_error(c, "tls oom"); return; @@ -12520,7 +12516,7 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { MG_ERROR(("EC private key: ASN.1 bad data")); } memmove(tls->ec_key, key.buf + 7, 32); - free((void *) key.buf); + mg_free((void *) key.buf); } else if (mg_parse_pem(opts->key, mg_str_s("PRIVATE KEY"), &key) == 0) { mg_error(c, "PKCS8 private key format is not supported"); } else { @@ -12532,10 +12528,10 @@ void mg_tls_free(struct mg_connection *c) { struct tls_data *tls = (struct tls_data *) c->tls; if (tls != NULL) { mg_iobuf_free(&tls->send); - free((void *) tls->cert_der.buf); - free((void *) tls->ca_der.buf); + mg_free((void *) tls->cert_der.buf); + mg_free((void *) tls->ca_der.buf); } - free(c->tls); + mg_free(c->tls); c->tls = NULL; } @@ -12551,7 +12547,7 @@ long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) { while (tls->send.len > 0 && (n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) { mg_iobuf_del(&tls->send, 0, (size_t) n); - } // if last chunk fails to be sent, it needs to be flushed + } // if last chunk fails to be sent, it needs to be flushed c->is_tls_throttled = (tls->send.len > 0 && n == MG_IO_WAIT); MG_VERBOSE(("%lu %ld %ld %ld %c %c", c->id, (long) len, (long) tls->send.len, n, was_throttled ? 'T' : 't', c->is_tls_throttled ? 'T' : 't')); @@ -14051,7 +14047,7 @@ void mg_tls_free(struct mg_connection *c) { #ifdef MBEDTLS_SSL_SESSION_TICKETS mbedtls_ssl_ticket_free(&tls->ticket); #endif - free(tls); + mg_free(tls); c->tls = NULL; } } @@ -14097,7 +14093,7 @@ static void debug_cb(void *c, int lev, const char *s, int n, const char *s2) { } void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { - struct mg_tls *tls = (struct mg_tls *) calloc(1, sizeof(*tls)); + struct mg_tls *tls = (struct mg_tls *) mg_calloc(1, sizeof(*tls)); int rc = 0; c->tls = tls; if (c->tls == NULL) { @@ -14140,7 +14136,7 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { char *host = mg_mprintf("%.*s", opts->name.len, opts->name.buf); mbedtls_ssl_set_hostname(&tls->ssl, host); MG_DEBUG(("%lu hostname verification: %s", c->id, host)); - free(host); + mg_free(host); } mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_REQUIRED); } @@ -14220,7 +14216,7 @@ void mg_tls_flush(struct mg_connection *c) { } void mg_tls_ctx_init(struct mg_mgr *mgr) { - struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) calloc(1, sizeof(*ctx)); + struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) mg_calloc(1, sizeof(*ctx)); if (ctx == NULL) { MG_ERROR(("TLS context init OOM")); } else { @@ -14243,7 +14239,7 @@ void mg_tls_ctx_free(struct mg_mgr *mgr) { #ifdef MBEDTLS_SSL_SESSION_TICKETS mbedtls_ssl_ticket_free(&ctx->tickets); #endif - free(ctx); + mg_free(ctx); mgr->tls_ctx = NULL; } } @@ -14368,12 +14364,12 @@ void mg_tls_free(struct mg_connection *c) { SSL_free(tls->ssl); SSL_CTX_free(tls->ctx); BIO_meth_free(tls->bm); - free(tls); + mg_free(tls); c->tls = NULL; } void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { - struct mg_tls *tls = (struct mg_tls *) calloc(1, sizeof(*tls)); + struct mg_tls *tls = (struct mg_tls *) mg_calloc(1, sizeof(*tls)); const char *id = "mongoose"; static unsigned char s_initialised = 0; BIO *bio = NULL; @@ -14466,7 +14462,7 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { X509_VERIFY_PARAM_set1_host(SSL_get0_param(tls->ssl), s, 0); #endif SSL_set_tlsext_host_name(tls->ssl, s); - free(s); + mg_free(s); } #endif #if MG_TLS == MG_TLS_WOLFSSL @@ -14852,8 +14848,8 @@ static void check(const bigint *bi); * @return A bigint context. */ NS_INTERNAL BI_CTX *bi_initialize(void) { - /* calloc() sets everything to zero */ - BI_CTX *ctx = (BI_CTX *) calloc(1, sizeof(BI_CTX)); + /* mg_calloc() sets everything to zero */ + BI_CTX *ctx = (BI_CTX *) mg_calloc(1, sizeof(BI_CTX)); /* the radix */ ctx->bi_radix = alloc(ctx, 2); @@ -14863,48 +14859,6 @@ NS_INTERNAL BI_CTX *bi_initialize(void) { return ctx; } -#if 0 -/** - * @brief Close the bigint context and free any resources. - * - * Free up any used memory - a check is done if all objects were not - * properly freed. - * @param ctx [in] The bigint session context. - */ -NS_INTERNAL void bi_terminate(BI_CTX *ctx) { - bi_depermanent(ctx->bi_radix); - bi_free(ctx, ctx->bi_radix); - - if (ctx->active_count != 0) { -#ifdef CONFIG_SSL_FULL_MODE - printf("bi_terminate: there were %d un-freed bigints\n", ctx->active_count); -#endif - abort(); - } - - bi_clear_cache(ctx); - free(ctx); -} - -/** - *@brief Clear the memory cache. - */ -NS_INTERNAL void bi_clear_cache(BI_CTX *ctx) { - bigint *p, *pn; - - if (ctx->free_list == NULL) return; - - for (p = ctx->free_list; p != NULL; p = pn) { - pn = p->next; - free(p->comps); - free(p); - } - - ctx->free_count = 0; - ctx->free_list = NULL; -} -#endif - /** * @brief Increment the number of references to this object. * It does not do a full copy. @@ -15735,9 +15689,9 @@ NS_INTERNAL int bi_compare(bigint *bia, bigint *bib) { static void more_comps(bigint *bi, int n) { if (n > bi->max_comps) { int max = MAX(bi->max_comps * 2, n); - void *p = calloc(1, (size_t) max * COMP_BYTE_SIZE); + void *p = mg_calloc(1, (size_t) max * COMP_BYTE_SIZE); if (p != NULL && bi->size > 0) memcpy(p, bi->comps, (size_t) bi->max_comps * COMP_BYTE_SIZE); - free(bi->comps); + mg_free(bi->comps); bi->max_comps = (short) max; bi->comps = (comp *) p; } @@ -15772,8 +15726,8 @@ static bigint *alloc(BI_CTX *ctx, int size) { more_comps(biR, size); } else { /* No free bigints available - create a new one. */ - biR = (bigint *) calloc(1, sizeof(bigint)); - biR->comps = (comp *) calloc(1, (size_t) size * COMP_BYTE_SIZE); + biR = (bigint *) mg_calloc(1, sizeof(bigint)); + biR->comps = (comp *) mg_calloc(1, (size_t) size * COMP_BYTE_SIZE); biR->max_comps = (short) size; /* give some space to spare */ } @@ -15962,7 +15916,7 @@ static void precompute_slide_window(BI_CTX *ctx, int window, bigint *g1) { k <<= 1; } - ctx->g = (bigint **) calloc(1, k * sizeof(bigint *)); + ctx->g = (bigint **) mg_calloc(1, k * sizeof(bigint *)); ctx->g[0] = bi_clone(ctx, g1); bi_permanent(ctx->g[0]); g2 = bi_residue(ctx, bi_square(ctx, ctx->g[0])); /* g^2 */ @@ -16013,7 +15967,7 @@ NS_INTERNAL bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp) { /* work out the slide constants */ precompute_slide_window(ctx, window_size, bi); #else /* just one constant */ - ctx->g = (bigint **) calloc(1, sizeof(bigint *)); + ctx->g = (bigint **) mg_calloc(1, sizeof(bigint *)); ctx->g[0] = bi_clone(ctx, bi); ctx->window = 1; bi_permanent(ctx->g[0]); @@ -16056,7 +16010,7 @@ NS_INTERNAL bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp) { bi_free(ctx, ctx->g[i]); } - free(ctx->g); + mg_free(ctx->g); bi_free(ctx, bi); bi_free(ctx, biexp); #if defined CONFIG_BIGINT_MONTGOMERY @@ -19911,6 +19865,18 @@ 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) { + return calloc(count, size); +} + +void mg_free(void *ptr) { + free(ptr); +} +#endif + #ifdef MG_ENABLE_LINES #line 1 "src/wifi_dummy.c" #endif diff --git a/mongoose.h b/mongoose.h index 304d5b73..bd6da61f 100644 --- a/mongoose.h +++ b/mongoose.h @@ -181,10 +181,11 @@ extern "C" { #include #include -#define calloc(a, b) mg_calloc(a, b) -#define free(a) vPortFree(a) -#define malloc(a) pvPortMalloc(a) -#define strdup(s) ((char *) mg_strdup(mg_str(s)).buf) +#define MG_ENABLE_CUSTOM_CALLOC 1 + +static inline void mg_free(void *ptr) { + vPortFree(ptr); +} // Re-route calloc/free to the FreeRTOS's functions, don't use stdlib static inline void *mg_calloc(size_t cnt, size_t size) { @@ -785,6 +786,10 @@ struct timeval { #define MG_ENABLE_LOG 1 #endif +#ifndef MG_ENABLE_CUSTOM_CALLOC +#define MG_ENABLE_CUSTOM_CALLOC 0 +#endif + #ifndef MG_ENABLE_CUSTOM_LOG #define MG_ENABLE_CUSTOM_LOG 0 // Let user define their own MG_LOG #endif @@ -1165,7 +1170,7 @@ struct mg_timer { #define MG_TIMER_REPEAT 1 // Call function periodically #define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set #define MG_TIMER_CALLED 4 // Timer function was called at least once -#define MG_TIMER_AUTODELETE 8 // free() timer when done +#define MG_TIMER_AUTODELETE 8 // mg_free() timer when done void (*fn)(void *); // Function to call void *arg; // Function argument struct mg_timer *next; // Linkage @@ -1240,6 +1245,8 @@ struct mg_str mg_unpacked(const char *path); // Packed file as mg_str #define assert(x) #endif +void *mg_calloc(size_t count, size_t size); +void mg_free(void *ptr); void mg_bzero(volatile unsigned char *buf, size_t len); bool mg_random(void *buf, size_t len); char *mg_random_str(char *buf, size_t len); @@ -3530,41 +3537,6 @@ struct mg_tcpip_driver_tms570_data { -#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC7) && MG_ENABLE_DRIVER_XMC7 - -struct mg_tcpip_driver_xmc7_data { - int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5 - uint8_t phy_addr; -}; - -#ifndef MG_TCPIP_PHY_ADDR -#define MG_TCPIP_PHY_ADDR 0 -#endif - -#ifndef MG_DRIVER_MDC_CR -#define MG_DRIVER_MDC_CR 3 -#endif - -#define MG_TCPIP_DRIVER_INIT(mgr) \ - do { \ - static struct mg_tcpip_driver_xmc7_data driver_data_; \ - static struct mg_tcpip_if mif_; \ - driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \ - driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \ - mif_.ip = MG_TCPIP_IP; \ - mif_.mask = MG_TCPIP_MASK; \ - mif_.gw = MG_TCPIP_GW; \ - mif_.driver = &mg_tcpip_driver_xmc7; \ - mif_.driver_data = &driver_data_; \ - MG_SET_MAC_ADDRESS(mif_.mac); \ - mg_tcpip_init(mgr, &mif_); \ - MG_INFO(("Driver: xmc7, MAC: %M", mg_print_mac, mif_.mac)); \ - } while (0) - -#endif - - - #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC) && MG_ENABLE_DRIVER_XMC struct mg_tcpip_driver_xmc_data { @@ -3611,6 +3583,41 @@ struct mg_tcpip_driver_xmc_data { #endif + +#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC7) && MG_ENABLE_DRIVER_XMC7 + +struct mg_tcpip_driver_xmc7_data { + int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5 + uint8_t phy_addr; +}; + +#ifndef MG_TCPIP_PHY_ADDR +#define MG_TCPIP_PHY_ADDR 0 +#endif + +#ifndef MG_DRIVER_MDC_CR +#define MG_DRIVER_MDC_CR 3 +#endif + +#define MG_TCPIP_DRIVER_INIT(mgr) \ + do { \ + static struct mg_tcpip_driver_xmc7_data driver_data_; \ + static struct mg_tcpip_if mif_; \ + driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \ + driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \ + mif_.ip = MG_TCPIP_IP; \ + mif_.mask = MG_TCPIP_MASK; \ + mif_.gw = MG_TCPIP_GW; \ + mif_.driver = &mg_tcpip_driver_xmc7; \ + mif_.driver_data = &driver_data_; \ + MG_SET_MAC_ADDRESS(mif_.mac); \ + mg_tcpip_init(mgr, &mif_); \ + MG_INFO(("Driver: xmc7, MAC: %M", mg_print_mac, mif_.mac)); \ + } while (0) + +#endif + + #ifdef __cplusplus } #endif diff --git a/src/arch_freertos.h b/src/arch_freertos.h index 7443e69f..2dc23b63 100644 --- a/src/arch_freertos.h +++ b/src/arch_freertos.h @@ -25,10 +25,11 @@ #include #include -#define calloc(a, b) mg_calloc(a, b) -#define free(a) vPortFree(a) -#define malloc(a) pvPortMalloc(a) -#define strdup(s) ((char *) mg_strdup(mg_str(s)).buf) +#define MG_ENABLE_CUSTOM_CALLOC 1 + +static inline void mg_free(void *ptr) { + vPortFree(ptr); +} // Re-route calloc/free to the FreeRTOS's functions, don't use stdlib static inline void *mg_calloc(size_t cnt, size_t size) { diff --git a/src/config.h b/src/config.h index 2043ca44..c9610b5b 100644 --- a/src/config.h +++ b/src/config.h @@ -4,6 +4,10 @@ #define MG_ENABLE_LOG 1 #endif +#ifndef MG_ENABLE_CUSTOM_CALLOC +#define MG_ENABLE_CUSTOM_CALLOC 0 +#endif + #ifndef MG_ENABLE_CUSTOM_LOG #define MG_ENABLE_CUSTOM_LOG 0 // Let user define their own MG_LOG #endif diff --git a/src/dns.c b/src/dns.c index 6fb66ef2..59541f89 100644 --- a/src/dns.c +++ b/src/dns.c @@ -18,7 +18,7 @@ static void mg_sendnsreq(struct mg_connection *, struct mg_str *, int, static void mg_dns_free(struct dns_data **head, struct dns_data *d) { LIST_DELETE(struct dns_data, head, d); - free(d); + mg_free(d); } void mg_resolve_cancel(struct mg_connection *c) { @@ -246,7 +246,7 @@ static void mg_sendnsreq(struct mg_connection *c, struct mg_str *name, int ms, } if (dnsc->c == NULL) { mg_error(c, "resolver"); - } else if ((d = (struct dns_data *) calloc(1, sizeof(*d))) == NULL) { + } else if ((d = (struct dns_data *) mg_calloc(1, sizeof(*d))) == NULL) { mg_error(c, "resolve OOM"); } else { struct dns_data *reqs = (struct dns_data *) c->mgr->active_dns_requests; diff --git a/src/fs.c b/src/fs.c index ad570a2f..58b4b578 100644 --- a/src/fs.c +++ b/src/fs.c @@ -3,12 +3,12 @@ #include "str.h" struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags) { - struct mg_fd *fd = (struct mg_fd *) calloc(1, sizeof(*fd)); + struct mg_fd *fd = (struct mg_fd *) mg_calloc(1, sizeof(*fd)); if (fd != NULL) { fd->fd = fs->op(path, flags); fd->fs = fs; if (fd->fd == NULL) { - free(fd); + mg_free(fd); fd = NULL; } } @@ -18,7 +18,7 @@ struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags) { void mg_fs_close(struct mg_fd *fd) { if (fd != NULL) { fd->fs->cl(fd->fd); - free(fd); + mg_free(fd); } } @@ -27,10 +27,10 @@ struct mg_str mg_file_read(struct mg_fs *fs, const char *path) { void *fp; fs->st(path, &result.len, NULL); if ((fp = fs->op(path, MG_FS_READ)) != NULL) { - result.buf = (char *) calloc(1, result.len + 1); + result.buf = (char *) mg_calloc(1, result.len + 1); if (result.buf != NULL && fs->rd(fp, (void *) result.buf, result.len) != result.len) { - free((void *) result.buf); + mg_free((void *) result.buf); result.buf = NULL; } fs->cl(fp); @@ -66,7 +66,7 @@ bool mg_file_printf(struct mg_fs *fs, const char *path, const char *fmt, ...) { data = mg_vmprintf(fmt, &ap); va_end(ap); result = mg_file_write(fs, path, data, strlen(data)); - free(data); + mg_free(data); return result; } diff --git a/src/fs_fat.c b/src/fs_fat.c index 030aafb3..3c5e7c06 100644 --- a/src/fs_fat.c +++ b/src/fs_fat.c @@ -74,7 +74,7 @@ static void *ff_open(const char *path, int flags) { if (flags & MG_FS_WRITE) mode |= FA_WRITE | FA_OPEN_ALWAYS | FA_OPEN_APPEND; if (f_open(&f, path, mode) == 0) { FIL *fp; - if ((fp = calloc(1, sizeof(*fp))) != NULL) { + if ((fp = mg_calloc(1, sizeof(*fp))) != NULL) { memcpy(fp, &f, sizeof(*fp)); return fp; } @@ -85,7 +85,7 @@ static void *ff_open(const char *path, int flags) { static void ff_close(void *fp) { if (fp != NULL) { f_close((FIL *) fp); - free(fp); + mg_free(fp); } } diff --git a/src/fs_packed.c b/src/fs_packed.c index 1c4caf75..7ce5b17e 100644 --- a/src/fs_packed.c +++ b/src/fs_packed.c @@ -72,7 +72,7 @@ static void *packed_open(const char *path, int flags) { struct packed_file *fp = NULL; if (data == NULL) return NULL; if (flags & MG_FS_WRITE) return NULL; - if ((fp = (struct packed_file *) calloc(1, sizeof(*fp))) != NULL) { + if ((fp = (struct packed_file *) mg_calloc(1, sizeof(*fp))) != NULL) { fp->size = size; fp->data = data; } @@ -80,7 +80,7 @@ static void *packed_open(const char *path, int flags) { } static void packed_close(void *fp) { - if (fp != NULL) free(fp); + if (fp != NULL) mg_free(fp); } static size_t packed_read(void *fd, void *buf, size_t len) { diff --git a/src/fs_posix.c b/src/fs_posix.c index 8a631fb2..220119a9 100644 --- a/src/fs_posix.c +++ b/src/fs_posix.c @@ -99,7 +99,7 @@ DIR *opendir(const char *name) { if (name == NULL) { SetLastError(ERROR_BAD_ARGUMENTS); - } else if ((d = (DIR *) calloc(1, sizeof(*d))) == NULL) { + } else if ((d = (DIR *) mg_calloc(1, sizeof(*d))) == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); } else { to_wchar(name, wpath, sizeof(wpath) / sizeof(wpath[0])); @@ -109,7 +109,7 @@ DIR *opendir(const char *name) { d->handle = FindFirstFileW(wpath, &d->info); d->result.d_name[0] = '\0'; } else { - free(d); + mg_free(d); d = NULL; } } @@ -121,7 +121,7 @@ int closedir(DIR *d) { if (d != NULL) { if (d->handle != INVALID_HANDLE_VALUE) result = FindClose(d->handle) ? 0 : -1; - free(d); + mg_free(d); } else { result = -1; SetLastError(ERROR_BAD_ARGUMENTS); diff --git a/src/iobuf.c b/src/iobuf.c index f152cc3a..390e9ce2 100644 --- a/src/iobuf.c +++ b/src/iobuf.c @@ -12,18 +12,17 @@ int mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) { new_size = roundup(new_size, io->align); if (new_size == 0) { mg_bzero(io->buf, io->size); - free(io->buf); + mg_free(io->buf); io->buf = NULL; io->len = io->size = 0; } else if (new_size != io->size) { - // NOTE(lsm): do not use realloc here. Use calloc/free only, to ease the - // porting to some obscure platforms like FreeRTOS - void *p = calloc(1, new_size); + // NOTE(lsm): do not use realloc here. Use mg_calloc/mg_free only + void *p = mg_calloc(1, new_size); if (p != NULL) { size_t len = new_size < io->len ? new_size : io->len; if (len > 0 && io->buf != NULL) memmove(p, io->buf, len); mg_bzero(io->buf, io->size); - free(io->buf); + mg_free(io->buf); io->buf = (unsigned char *) p; io->size = new_size; } else { diff --git a/src/json.c b/src/json.c index ea11ccc7..0c78fa33 100644 --- a/src/json.c +++ b/src/json.c @@ -320,10 +320,10 @@ char *mg_json_get_str(struct mg_str json, const char *path) { char *result = NULL; int len = 0, off = mg_json_get(json, path, &len); if (off >= 0 && len > 1 && json.buf[off] == '"') { - if ((result = (char *) calloc(1, (size_t) len)) != NULL && + if ((result = (char *) mg_calloc(1, (size_t) len)) != NULL && !mg_json_unescape(mg_str_n(json.buf + off + 1, (size_t) (len - 2)), result, (size_t) len)) { - free(result); + mg_free(result); result = NULL; } } @@ -334,7 +334,7 @@ char *mg_json_get_b64(struct mg_str json, const char *path, int *slen) { char *result = NULL; int len = 0, off = mg_json_get(json, path, &len); if (off >= 0 && json.buf[off] == '"' && len > 1 && - (result = (char *) calloc(1, (size_t) len)) != NULL) { + (result = (char *) mg_calloc(1, (size_t) len)) != NULL) { size_t k = mg_base64_decode(json.buf + off + 1, (size_t) (len - 2), result, (size_t) len); if (slen != NULL) *slen = (int) k; @@ -346,7 +346,7 @@ char *mg_json_get_hex(struct mg_str json, const char *path, int *slen) { char *result = NULL; int len = 0, off = mg_json_get(json, path, &len); if (off >= 0 && json.buf[off] == '"' && len > 1 && - (result = (char *) calloc(1, (size_t) len / 2)) != NULL) { + (result = (char *) mg_calloc(1, (size_t) len / 2)) != NULL) { int i; for (i = 0; i < len - 2; i += 2) { mg_str_to_num(mg_str_n(json.buf + off + 1 + i, 2), 16, &result[i >> 1], diff --git a/src/net.c b/src/net.c index 2510b49a..84315989 100644 --- a/src/net.c +++ b/src/net.c @@ -126,7 +126,7 @@ bool mg_aton(struct mg_str str, struct mg_addr *addr) { struct mg_connection *mg_alloc_conn(struct mg_mgr *mgr) { struct mg_connection *c = - (struct mg_connection *) calloc(1, sizeof(*c) + mgr->extraconnsize); + (struct mg_connection *) mg_calloc(1, sizeof(*c) + mgr->extraconnsize); if (c != NULL) { c->mgr = mgr; c->send.align = c->recv.align = c->rtls.align = MG_IO_SIZE; @@ -153,7 +153,7 @@ void mg_close_conn(struct mg_connection *c) { mg_iobuf_free(&c->send); mg_iobuf_free(&c->rtls); mg_bzero((unsigned char *) c, sizeof(*c)); - free(c); + mg_free(c); } struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *url, @@ -186,7 +186,7 @@ struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url, } else if (!mg_open_listener(c, url)) { MG_ERROR(("Failed: %s", url)); MG_PROF_FREE(c); - free(c); + mg_free(c); c = NULL; } else { c->is_listening = 1; @@ -217,9 +217,9 @@ struct mg_connection *mg_wrapfd(struct mg_mgr *mgr, int fd, struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds, unsigned flags, void (*fn)(void *), void *arg) { - struct mg_timer *t = (struct mg_timer *) calloc(1, sizeof(*t)); + struct mg_timer *t = (struct mg_timer *) mg_calloc(1, sizeof(*t)); if (t != NULL) { - flags |= MG_TIMER_AUTODELETE; // We have calloc-ed it, so autodelete + flags |= MG_TIMER_AUTODELETE; // We have mg_calloc-ed it, so autodelete mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg); } return t; @@ -236,7 +236,7 @@ long mg_io_recv(struct mg_connection *c, void *buf, size_t len) { void mg_mgr_free(struct mg_mgr *mgr) { struct mg_connection *c; struct mg_timer *tmp, *t = mgr->timers; - while (t != NULL) tmp = t->next, free(t), t = tmp; + while (t != NULL) tmp = t->next, mg_free(t), t = tmp; mgr->timers = NULL; // Important. Next call to poll won't touch timers for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1; mg_mgr_poll(mgr, 0); diff --git a/src/net_builtin.c b/src/net_builtin.c index 37b64b51..c840d5f9 100644 --- a/src/net_builtin.c +++ b/src/net_builtin.c @@ -1083,10 +1083,10 @@ void mg_tcpip_init(struct mg_mgr *mgr, struct mg_tcpip_if *ifp) { MG_ERROR(("driver init failed")); } else { size_t framesize = 1540; - ifp->tx.buf = (char *) calloc(1, framesize), ifp->tx.len = framesize; + ifp->tx.buf = (char *) mg_calloc(1, framesize), ifp->tx.len = framesize; if (ifp->recv_queue.size == 0) ifp->recv_queue.size = ifp->driver->rx ? framesize : 8192; - ifp->recv_queue.buf = (char *) calloc(1, ifp->recv_queue.size); + ifp->recv_queue.buf = (char *) mg_calloc(1, ifp->recv_queue.size); ifp->timer_1000ms = mg_millis(); mgr->ifp = ifp; ifp->mgr = mgr; @@ -1102,8 +1102,8 @@ void mg_tcpip_init(struct mg_mgr *mgr, struct mg_tcpip_if *ifp) { } void mg_tcpip_free(struct mg_tcpip_if *ifp) { - free(ifp->recv_queue.buf); - free(ifp->tx.buf); + mg_free(ifp->recv_queue.buf); + mg_free(ifp->tx.buf); } static void send_syn(struct mg_connection *c) { diff --git a/src/ota_mcxn.c b/src/ota_mcxn.c index 3c17b18a..acd041bb 100644 --- a/src/ota_mcxn.c +++ b/src/ota_mcxn.c @@ -150,7 +150,7 @@ fwxit: // try to swap (honor dual image), otherwise just overwrite MG_IRAM static void single_bank_swap(char *p1, char *p2, size_t s, size_t ss) { - char *tmp = calloc(1, ss); + char *tmp = mg_calloc(1, ss); // no stdlib calls here for (size_t ofs = 0; ofs < s; ofs += ss) { if (tmp != NULL) diff --git a/src/ota_picosdk.c b/src/ota_picosdk.c index d22f8325..b6900ccf 100644 --- a/src/ota_picosdk.c +++ b/src/ota_picosdk.c @@ -100,7 +100,7 @@ static bool __no_inline_not_in_flash_func(mg_picosdk_write)(void *addr, static void __no_inline_not_in_flash_func(single_bank_swap)(char *p1, char *p2, size_t s, size_t ss) { - char *tmp = calloc(1, ss); + char *tmp = mg_calloc(1, ss); if (tmp == NULL) return; #if PICO_RP2040 uint32_t xip[256 / sizeof(uint32_t)]; diff --git a/src/rpc.c b/src/rpc.c index 9efe9671..0e19ebb2 100644 --- a/src/rpc.c +++ b/src/rpc.c @@ -3,7 +3,7 @@ void mg_rpc_add(struct mg_rpc **head, struct mg_str method, void (*fn)(struct mg_rpc_req *), void *fn_data) { - struct mg_rpc *rpc = (struct mg_rpc *) calloc(1, sizeof(*rpc)); + struct mg_rpc *rpc = (struct mg_rpc *) mg_calloc(1, sizeof(*rpc)); if (rpc != NULL) { rpc->method = mg_strdup(method); rpc->fn = fn; @@ -17,8 +17,8 @@ void mg_rpc_del(struct mg_rpc **head, void (*fn)(struct mg_rpc_req *)) { while ((r = *head) != NULL) { if (r->fn == fn || fn == NULL) { *head = r->next; - free((void *) r->method.buf); - free(r); + mg_free((void *) r->method.buf); + mg_free(r); } else { head = &(*head)->next; } diff --git a/src/ssi.c b/src/ssi.c index 788efb81..c5bd2cb5 100644 --- a/src/ssi.c +++ b/src/ssi.c @@ -31,7 +31,7 @@ static char *mg_ssi(const char *path, const char *root, int depth) { if (depth < MG_MAX_SSI_DEPTH && (data = mg_ssi(tmp, root, depth + 1)) != NULL) { mg_iobuf_add(&b, b.len, data, strlen(data)); - free(data); + mg_free(data); } else { MG_ERROR(("%s: file=%s error or too deep", path, arg)); } @@ -41,7 +41,7 @@ static char *mg_ssi(const char *path, const char *root, int depth) { if (depth < MG_MAX_SSI_DEPTH && (data = mg_ssi(tmp, root, depth + 1)) != NULL) { mg_iobuf_add(&b, b.len, data, strlen(data)); - free(data); + mg_free(data); } else { MG_ERROR(("%s: virtual=%s error or too deep", path, arg)); } @@ -87,7 +87,7 @@ void mg_http_serve_ssi(struct mg_connection *c, const char *root, const char *headers = "Content-Type: text/html; charset=utf-8\r\n"; char *data = mg_ssi(fullpath, root, 0); mg_http_reply(c, 200, headers, "%s", data == NULL ? "" : data); - free(data); + mg_free(data); } #else void mg_http_serve_ssi(struct mg_connection *c, const char *root, diff --git a/src/str.c b/src/str.c index 0e52d28d..fc8f715f 100644 --- a/src/str.c +++ b/src/str.c @@ -26,7 +26,7 @@ int mg_casecmp(const char *s1, const char *s2) { struct mg_str mg_strdup(const struct mg_str s) { struct mg_str r = {NULL, 0}; if (s.len > 0 && s.buf != NULL) { - char *sc = (char *) calloc(1, s.len + 1); + char *sc = (char *) mg_calloc(1, s.len + 1); if (sc != NULL) { memcpy(sc, s.buf, s.len); sc[s.len] = '\0'; diff --git a/src/timer.c b/src/timer.c index e747b667..8253452a 100644 --- a/src/timer.c +++ b/src/timer.c @@ -38,7 +38,7 @@ void mg_timer_poll(struct mg_timer **head, uint64_t now_ms) { // If this timer is not repeating and marked AUTODELETE, remove it if (!(t->flags & MG_TIMER_REPEAT) && (t->flags & MG_TIMER_AUTODELETE)) { mg_timer_free(head, t); - free(t); + mg_free(t); } } } diff --git a/src/timer.h b/src/timer.h index effc34c3..e022f156 100644 --- a/src/timer.h +++ b/src/timer.h @@ -10,7 +10,7 @@ struct mg_timer { #define MG_TIMER_REPEAT 1 // Call function periodically #define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set #define MG_TIMER_CALLED 4 // Timer function was called at least once -#define MG_TIMER_AUTODELETE 8 // free() timer when done +#define MG_TIMER_AUTODELETE 8 // mg_free() timer when done void (*fn)(void *); // Function to call void *arg; // Function argument struct mg_timer *next; // Linkage diff --git a/src/tls_builtin.c b/src/tls_builtin.c index acafa6e6..6d16542d 100644 --- a/src/tls_builtin.c +++ b/src/tls_builtin.c @@ -34,13 +34,13 @@ // refer to RFC8446#A.1 enum mg_tls_hs_state { // Client state machine: - MG_TLS_STATE_CLIENT_START, // Send ClientHello - MG_TLS_STATE_CLIENT_WAIT_SH, // Wait for ServerHello - MG_TLS_STATE_CLIENT_WAIT_EE, // Wait for EncryptedExtensions - MG_TLS_STATE_CLIENT_WAIT_CERT, // Wait for Certificate - MG_TLS_STATE_CLIENT_WAIT_CV, // Wait for CertificateVerify - MG_TLS_STATE_CLIENT_WAIT_FINISH, // Wait for Finish - MG_TLS_STATE_CLIENT_CONNECTED, // Done + MG_TLS_STATE_CLIENT_START, // Send ClientHello + MG_TLS_STATE_CLIENT_WAIT_SH, // Wait for ServerHello + MG_TLS_STATE_CLIENT_WAIT_EE, // Wait for EncryptedExtensions + MG_TLS_STATE_CLIENT_WAIT_CERT, // Wait for Certificate + MG_TLS_STATE_CLIENT_WAIT_CV, // Wait for CertificateVerify + MG_TLS_STATE_CLIENT_WAIT_FINISH, // Wait for Finish + MG_TLS_STATE_CLIENT_CONNECTED, // Done // Server state machine: MG_TLS_STATE_SERVER_START, // Wait for ClientHello @@ -424,7 +424,7 @@ static void mg_tls_encrypt(struct mg_connection *c, const uint8_t *msg, nonce[8] ^= (uint8_t) ((seq >> 24) & 255U); nonce[9] ^= (uint8_t) ((seq >> 16) & 255U); nonce[10] ^= (uint8_t) ((seq >> 8) & 255U); - nonce[11] ^= (uint8_t) ((seq) &255U); + nonce[11] ^= (uint8_t) ((seq) & 255U); mg_iobuf_add(wio, wio->len, hdr, sizeof(hdr)); mg_iobuf_resize(wio, wio->len + encsz); @@ -436,7 +436,7 @@ static void mg_tls_encrypt(struct mg_connection *c, const uint8_t *msg, (void) tag; // tag is only used in aes gcm { size_t maxlen = MG_IO_SIZE > 16384 ? 16384 : MG_IO_SIZE; - uint8_t *enc = (uint8_t *) calloc(1, maxlen + 256 + 1); + uint8_t *enc = (uint8_t *) mg_calloc(1, maxlen + 256 + 1); if (enc == NULL) { mg_error(c, "TLS OOM"); return; @@ -445,7 +445,7 @@ static void mg_tls_encrypt(struct mg_connection *c, const uint8_t *msg, sizeof(associated_data), outmsg, msgsz + 1); memmove(outmsg, enc, n); - free(enc); + mg_free(enc); } } #else @@ -503,10 +503,10 @@ static int mg_tls_recv_record(struct mg_connection *c) { nonce[8] ^= (uint8_t) ((seq >> 24) & 255U); nonce[9] ^= (uint8_t) ((seq >> 16) & 255U); nonce[10] ^= (uint8_t) ((seq >> 8) & 255U); - nonce[11] ^= (uint8_t) ((seq) &255U); + nonce[11] ^= (uint8_t) ((seq) & 255U); #if CHACHA20 { - uint8_t *dec = (uint8_t *) calloc(1, msgsz); + uint8_t *dec = (uint8_t *) mg_calloc(1, msgsz); size_t n; if (dec == NULL) { mg_error(c, "TLS OOM"); @@ -514,7 +514,7 @@ static int mg_tls_recv_record(struct mg_connection *c) { } n = mg_chacha20_poly1305_decrypt(dec, key, nonce, msg, msgsz); memmove(msg, dec, n); - free(dec); + mg_free(dec); } #else mg_gcm_initialize(); @@ -687,7 +687,7 @@ static void mg_tls_server_send_cert(struct mg_connection *c) { int send_ca = !c->is_client && tls->ca_der.len > 0; // server DER certificate + CA (optional) size_t n = tls->cert_der.len + (send_ca ? tls->ca_der.len + 5 : 0); - uint8_t *cert = (uint8_t *) calloc(1, 13 + n); + uint8_t *cert = (uint8_t *) mg_calloc(1, 13 + n); if (cert == NULL) { mg_error(c, "tls cert oom"); return; @@ -710,7 +710,7 @@ static void mg_tls_server_send_cert(struct mg_connection *c) { } mg_sha256_update(&tls->sha256, cert, 13 + n); mg_tls_encrypt(c, cert, 13 + n, MG_TLS_HANDSHAKE); - free(cert); + mg_free(cert); } // type adapter between uECC hash context and our sha256 implementation @@ -1523,9 +1523,7 @@ static void mg_tls_client_handshake(struct mg_connection *c) { c->is_tls_hs = 0; mg_call(c, MG_EV_TLS_HS, NULL); break; - default: - mg_error(c, "unexpected client state: %d", tls->state); - break; + default: mg_error(c, "unexpected client state: %d", tls->state); break; } } @@ -1552,9 +1550,7 @@ static void mg_tls_server_handshake(struct mg_connection *c) { tls->state = MG_TLS_STATE_SERVER_CONNECTED; c->is_tls_hs = 0; return; - default: - mg_error(c, "unexpected server state: %d", tls->state); - break; + default: mg_error(c, "unexpected server state: %d", tls->state); break; } } @@ -1570,8 +1566,8 @@ void mg_tls_handshake(struct mg_connection *c) { while (tls->send.len > 0 && (n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) { mg_iobuf_del(&tls->send, 0, (size_t) n); - } // if last chunk fails to be sent, it will be sent with first app data, - // otherwise, it needs to be flushed + } // if last chunk fails to be sent, it will be sent with first app data, + // otherwise, it needs to be flushed } static int mg_parse_pem(const struct mg_str pem, const struct mg_str label, @@ -1587,7 +1583,7 @@ static int mg_parse_pem(const struct mg_str pem, const struct mg_str label, if (mg_strcmp(caps[1], label) != 0 || mg_strcmp(caps[3], label) != 0) { return -1; // bad label } - if ((s = (char *) calloc(1, caps[2].len)) == NULL) { + if ((s = (char *) mg_calloc(1, caps[2].len)) == NULL) { return -1; } @@ -1599,7 +1595,7 @@ static int mg_parse_pem(const struct mg_str pem, const struct mg_str label, } m = mg_base64_decode(s, n, s, n); if (m == 0) { - free(s); + mg_free(s); return -1; } der->buf = s; @@ -1609,7 +1605,8 @@ static int mg_parse_pem(const struct mg_str pem, const struct mg_str label, void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { struct mg_str key; - struct tls_data *tls = (struct tls_data *) calloc(1, sizeof(struct tls_data)); + struct tls_data *tls = + (struct tls_data *) mg_calloc(1, sizeof(struct tls_data)); if (tls == NULL) { mg_error(c, "tls oom"); return; @@ -1674,7 +1671,7 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { MG_ERROR(("EC private key: ASN.1 bad data")); } memmove(tls->ec_key, key.buf + 7, 32); - free((void *) key.buf); + mg_free((void *) key.buf); } else if (mg_parse_pem(opts->key, mg_str_s("PRIVATE KEY"), &key) == 0) { mg_error(c, "PKCS8 private key format is not supported"); } else { @@ -1686,10 +1683,10 @@ void mg_tls_free(struct mg_connection *c) { struct tls_data *tls = (struct tls_data *) c->tls; if (tls != NULL) { mg_iobuf_free(&tls->send); - free((void *) tls->cert_der.buf); - free((void *) tls->ca_der.buf); + mg_free((void *) tls->cert_der.buf); + mg_free((void *) tls->ca_der.buf); } - free(c->tls); + mg_free(c->tls); c->tls = NULL; } @@ -1705,7 +1702,7 @@ long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) { while (tls->send.len > 0 && (n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) { mg_iobuf_del(&tls->send, 0, (size_t) n); - } // if last chunk fails to be sent, it needs to be flushed + } // if last chunk fails to be sent, it needs to be flushed c->is_tls_throttled = (tls->send.len > 0 && n == MG_IO_WAIT); MG_VERBOSE(("%lu %ld %ld %ld %c %c", c->id, (long) len, (long) tls->send.len, n, was_throttled ? 'T' : 't', c->is_tls_throttled ? 'T' : 't')); diff --git a/src/tls_mbed.c b/src/tls_mbed.c index 1c32de46..566010a5 100644 --- a/src/tls_mbed.c +++ b/src/tls_mbed.c @@ -51,7 +51,7 @@ void mg_tls_free(struct mg_connection *c) { #ifdef MBEDTLS_SSL_SESSION_TICKETS mbedtls_ssl_ticket_free(&tls->ticket); #endif - free(tls); + mg_free(tls); c->tls = NULL; } } @@ -97,7 +97,7 @@ static void debug_cb(void *c, int lev, const char *s, int n, const char *s2) { } void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { - struct mg_tls *tls = (struct mg_tls *) calloc(1, sizeof(*tls)); + struct mg_tls *tls = (struct mg_tls *) mg_calloc(1, sizeof(*tls)); int rc = 0; c->tls = tls; if (c->tls == NULL) { @@ -140,7 +140,7 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { char *host = mg_mprintf("%.*s", opts->name.len, opts->name.buf); mbedtls_ssl_set_hostname(&tls->ssl, host); MG_DEBUG(("%lu hostname verification: %s", c->id, host)); - free(host); + mg_free(host); } mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_REQUIRED); } @@ -220,7 +220,7 @@ void mg_tls_flush(struct mg_connection *c) { } void mg_tls_ctx_init(struct mg_mgr *mgr) { - struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) calloc(1, sizeof(*ctx)); + struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) mg_calloc(1, sizeof(*ctx)); if (ctx == NULL) { MG_ERROR(("TLS context init OOM")); } else { @@ -243,7 +243,7 @@ void mg_tls_ctx_free(struct mg_mgr *mgr) { #ifdef MBEDTLS_SSL_SESSION_TICKETS mbedtls_ssl_ticket_free(&ctx->tickets); #endif - free(ctx); + mg_free(ctx); mgr->tls_ctx = NULL; } } diff --git a/src/tls_openssl.c b/src/tls_openssl.c index 3b236c0f..33b8e0ae 100644 --- a/src/tls_openssl.c +++ b/src/tls_openssl.c @@ -114,12 +114,12 @@ void mg_tls_free(struct mg_connection *c) { SSL_free(tls->ssl); SSL_CTX_free(tls->ctx); BIO_meth_free(tls->bm); - free(tls); + mg_free(tls); c->tls = NULL; } void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { - struct mg_tls *tls = (struct mg_tls *) calloc(1, sizeof(*tls)); + struct mg_tls *tls = (struct mg_tls *) mg_calloc(1, sizeof(*tls)); const char *id = "mongoose"; static unsigned char s_initialised = 0; BIO *bio = NULL; @@ -212,7 +212,7 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { X509_VERIFY_PARAM_set1_host(SSL_get0_param(tls->ssl), s, 0); #endif SSL_set_tlsext_host_name(tls->ssl, s); - free(s); + mg_free(s); } #endif #if MG_TLS == MG_TLS_WOLFSSL diff --git a/src/tls_rsa.c b/src/tls_rsa.c index 17c19954..7122dd6a 100644 --- a/src/tls_rsa.c +++ b/src/tls_rsa.c @@ -309,8 +309,8 @@ static void check(const bigint *bi); * @return A bigint context. */ NS_INTERNAL BI_CTX *bi_initialize(void) { - /* calloc() sets everything to zero */ - BI_CTX *ctx = (BI_CTX *) calloc(1, sizeof(BI_CTX)); + /* mg_calloc() sets everything to zero */ + BI_CTX *ctx = (BI_CTX *) mg_calloc(1, sizeof(BI_CTX)); /* the radix */ ctx->bi_radix = alloc(ctx, 2); @@ -320,48 +320,6 @@ NS_INTERNAL BI_CTX *bi_initialize(void) { return ctx; } -#if 0 -/** - * @brief Close the bigint context and free any resources. - * - * Free up any used memory - a check is done if all objects were not - * properly freed. - * @param ctx [in] The bigint session context. - */ -NS_INTERNAL void bi_terminate(BI_CTX *ctx) { - bi_depermanent(ctx->bi_radix); - bi_free(ctx, ctx->bi_radix); - - if (ctx->active_count != 0) { -#ifdef CONFIG_SSL_FULL_MODE - printf("bi_terminate: there were %d un-freed bigints\n", ctx->active_count); -#endif - abort(); - } - - bi_clear_cache(ctx); - free(ctx); -} - -/** - *@brief Clear the memory cache. - */ -NS_INTERNAL void bi_clear_cache(BI_CTX *ctx) { - bigint *p, *pn; - - if (ctx->free_list == NULL) return; - - for (p = ctx->free_list; p != NULL; p = pn) { - pn = p->next; - free(p->comps); - free(p); - } - - ctx->free_count = 0; - ctx->free_list = NULL; -} -#endif - /** * @brief Increment the number of references to this object. * It does not do a full copy. @@ -1192,9 +1150,9 @@ NS_INTERNAL int bi_compare(bigint *bia, bigint *bib) { static void more_comps(bigint *bi, int n) { if (n > bi->max_comps) { int max = MAX(bi->max_comps * 2, n); - void *p = calloc(1, (size_t) max * COMP_BYTE_SIZE); + void *p = mg_calloc(1, (size_t) max * COMP_BYTE_SIZE); if (p != NULL && bi->size > 0) memcpy(p, bi->comps, (size_t) bi->max_comps * COMP_BYTE_SIZE); - free(bi->comps); + mg_free(bi->comps); bi->max_comps = (short) max; bi->comps = (comp *) p; } @@ -1229,8 +1187,8 @@ static bigint *alloc(BI_CTX *ctx, int size) { more_comps(biR, size); } else { /* No free bigints available - create a new one. */ - biR = (bigint *) calloc(1, sizeof(bigint)); - biR->comps = (comp *) calloc(1, (size_t) size * COMP_BYTE_SIZE); + biR = (bigint *) mg_calloc(1, sizeof(bigint)); + biR->comps = (comp *) mg_calloc(1, (size_t) size * COMP_BYTE_SIZE); biR->max_comps = (short) size; /* give some space to spare */ } @@ -1419,7 +1377,7 @@ static void precompute_slide_window(BI_CTX *ctx, int window, bigint *g1) { k <<= 1; } - ctx->g = (bigint **) calloc(1, k * sizeof(bigint *)); + ctx->g = (bigint **) mg_calloc(1, k * sizeof(bigint *)); ctx->g[0] = bi_clone(ctx, g1); bi_permanent(ctx->g[0]); g2 = bi_residue(ctx, bi_square(ctx, ctx->g[0])); /* g^2 */ @@ -1470,7 +1428,7 @@ NS_INTERNAL bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp) { /* work out the slide constants */ precompute_slide_window(ctx, window_size, bi); #else /* just one constant */ - ctx->g = (bigint **) calloc(1, sizeof(bigint *)); + ctx->g = (bigint **) mg_calloc(1, sizeof(bigint *)); ctx->g[0] = bi_clone(ctx, bi); ctx->window = 1; bi_permanent(ctx->g[0]); @@ -1513,7 +1471,7 @@ NS_INTERNAL bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp) { bi_free(ctx, ctx->g[i]); } - free(ctx->g); + mg_free(ctx->g); bi_free(ctx, bi); bi_free(ctx, biexp); #if defined CONFIG_BIGINT_MONTGOMERY diff --git a/src/util.c b/src/util.c index 538036d6..51712520 100644 --- a/src/util.c +++ b/src/util.c @@ -199,3 +199,15 @@ void mg_delayms(unsigned int ms) { uint64_t to = mg_millis() + ms + 1; while (mg_millis() < to) (void) 0; } + + +#if MG_ENABLE_CUSTOM_CALLOC +#else +void *mg_calloc(size_t count, size_t size) { + return calloc(count, size); +} + +void mg_free(void *ptr) { + free(ptr); +} +#endif diff --git a/src/util.h b/src/util.h index 7e14e703..7e75cddf 100644 --- a/src/util.h +++ b/src/util.h @@ -11,6 +11,8 @@ #define assert(x) #endif +void *mg_calloc(size_t count, size_t size); +void mg_free(void *ptr); void mg_bzero(volatile unsigned char *buf, size_t len); bool mg_random(void *buf, size_t len); char *mg_random_str(char *buf, size_t len); From f5e2c68c8b26bf1ec7f2bd4818a938be20bae30c Mon Sep 17 00:00:00 2001 From: "Sergio R. Caprile" Date: Tue, 24 Jun 2025 16:25:19 -0300 Subject: [PATCH 2/2] update examples --- mongoose.c | 54 +++++++++++++++++++- src/fs.c | 1 + src/fs_packed.c | 1 + src/json.c | 1 + src/net.c | 2 +- src/rpc.c | 1 + src/ssi.c | 1 + src/str.c | 1 + src/timer.c | 1 + src/tls_mbed.c | 1 + src/tls_openssl.c | 1 + src/tls_rsa.c | 43 ++++++++++++++++ test/unit_test.c | 30 +++++------ tutorials/core/multi-threaded/main.c | 2 +- tutorials/http/device-dashboard/net.c | 4 +- tutorials/http/uart-bridge/esp32/main/main.c | 6 +-- tutorials/http/uart-bridge/net.c | 4 +- tutorials/http/video-stream/main.c | 2 +- tutorials/mqtt/mqtt-dashboard/device/net.c | 6 +-- tutorials/mqtt/mqtt-server/main.c | 4 +- tutorials/tcp/modbus-dashboard/main.c | 2 +- tutorials/tcp/modbus-dashboard/net.c | 4 +- tutorials/tcpip/pcap-driver/main.c | 2 +- tutorials/tcpip/tap-driver/main.c | 8 +-- tutorials/websocket/websocket-client/main.c | 9 +++- tutorials/websocket/websocket-server/main.c | 15 ++++-- tutorials/webui/webui-plain/main.c | 7 ++- 27 files changed, 166 insertions(+), 47 deletions(-) diff --git a/mongoose.c b/mongoose.c index 223a4e4f..f34eb139 100644 --- a/mongoose.c +++ b/mongoose.c @@ -821,6 +821,7 @@ size_t mg_vxprintf(void (*out)(char, void *), void *param, const char *fmt, + struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags) { struct mg_fd *fd = (struct mg_fd *) mg_calloc(1, sizeof(*fd)); if (fd != NULL) { @@ -1048,6 +1049,7 @@ struct mg_fs mg_fs_fat = {ff_stat, ff_list, ff_open, ff_close, ff_read, + struct packed_file { const char *data; size_t size; @@ -2676,6 +2678,7 @@ void mg_iobuf_free(struct mg_iobuf *io) { + static const char *escapeseq(int esc) { return esc ? "\b\f\n\r\t\\\"" : "bfnrt\\\""; } @@ -4096,7 +4099,7 @@ struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds, unsigned flags, void (*fn)(void *), void *arg) { struct mg_timer *t = (struct mg_timer *) mg_calloc(1, sizeof(*t)); if (t != NULL) { - flags |= MG_TIMER_AUTODELETE; // We have mg_calloc-ed it, so autodelete + flags |= MG_TIMER_AUTODELETE; // We have alloc'ed it, so autodelete mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg); } return t; @@ -7864,6 +7867,7 @@ void mg_queue_del(struct mg_queue *q, size_t len) { + void mg_rpc_add(struct mg_rpc **head, struct mg_str method, void (*fn)(struct mg_rpc_req *), void *fn_data) { struct mg_rpc *rpc = (struct mg_rpc *) mg_calloc(1, sizeof(*rpc)); @@ -9381,6 +9385,7 @@ void mg_mgr_poll(struct mg_mgr *mgr, int ms) { + #ifndef MG_MAX_SSI_DEPTH #define MG_MAX_SSI_DEPTH 5 #endif @@ -9481,6 +9486,7 @@ void mg_http_serve_ssi(struct mg_connection *c, const char *root, #endif + struct mg_str mg_str_s(const char *s) { struct mg_str str = {(char *) s, s == NULL ? 0 : strlen(s)}; return str; @@ -9669,6 +9675,7 @@ bool mg_str_to_num(struct mg_str str, int base, void *val, size_t val_len) { + void mg_timer_init(struct mg_timer **head, struct mg_timer *t, uint64_t ms, unsigned flags, void (*fn)(void *), void *arg) { t->period_ms = ms, t->expire = 0; @@ -13999,6 +14006,7 @@ void mg_tls_ctx_free(struct mg_mgr *mgr) { + #if MG_TLS == MG_TLS_MBED #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000 @@ -14251,6 +14259,7 @@ void mg_tls_ctx_free(struct mg_mgr *mgr) { + #if MG_TLS == MG_TLS_OPENSSL || MG_TLS == MG_TLS_WOLFSSL static int tls_err_cb(const char *s, size_t len, void *c) { @@ -14540,6 +14549,7 @@ void mg_tls_ctx_free(struct mg_mgr *mgr) { + #if MG_TLS == MG_TLS_BUILTIN #define NS_INTERNAL static @@ -14859,6 +14869,48 @@ NS_INTERNAL BI_CTX *bi_initialize(void) { return ctx; } +#if 0 +/** + * @brief Close the bigint context and free any resources. + * + * Free up any used memory - a check is done if all objects were not + * properly freed. + * @param ctx [in] The bigint session context. + */ +NS_INTERNAL void bi_terminate(BI_CTX *ctx) { + bi_depermanent(ctx->bi_radix); + bi_free(ctx, ctx->bi_radix); + + if (ctx->active_count != 0) { +#ifdef CONFIG_SSL_FULL_MODE + printf("bi_terminate: there were %d un-freed bigints\n", ctx->active_count); +#endif + abort(); + } + + bi_clear_cache(ctx); + mg_free(ctx); +} + +/** + *@brief Clear the memory cache. + */ +NS_INTERNAL void bi_clear_cache(BI_CTX *ctx) { + bigint *p, *pn; + + if (ctx->free_list == NULL) return; + + for (p = ctx->free_list; p != NULL; p = pn) { + pn = p->next; + mg_free(p->comps); + mg_free(p); + } + + ctx->free_count = 0; + ctx->free_list = NULL; +} +#endif + /** * @brief Increment the number of references to this object. * It does not do a full copy. diff --git a/src/fs.c b/src/fs.c index 58b4b578..9d00c8e1 100644 --- a/src/fs.c +++ b/src/fs.c @@ -1,6 +1,7 @@ #include "fs.h" #include "printf.h" #include "str.h" +#include "util.h" struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags) { struct mg_fd *fd = (struct mg_fd *) mg_calloc(1, sizeof(*fd)); diff --git a/src/fs_packed.c b/src/fs_packed.c index 7ce5b17e..bcb09fc7 100644 --- a/src/fs_packed.c +++ b/src/fs_packed.c @@ -1,6 +1,7 @@ #include "fs.h" #include "printf.h" #include "str.h" +#include "util.h" struct packed_file { const char *data; diff --git a/src/json.c b/src/json.c index 0c78fa33..bfcc0c88 100644 --- a/src/json.c +++ b/src/json.c @@ -1,6 +1,7 @@ #include "json.h" #include "base64.h" #include "fmt.h" +#include "util.h" static const char *escapeseq(int esc) { return esc ? "\b\f\n\r\t\\\"" : "bfnrt\\\""; diff --git a/src/net.c b/src/net.c index 84315989..c46212ff 100644 --- a/src/net.c +++ b/src/net.c @@ -219,7 +219,7 @@ struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds, unsigned flags, void (*fn)(void *), void *arg) { struct mg_timer *t = (struct mg_timer *) mg_calloc(1, sizeof(*t)); if (t != NULL) { - flags |= MG_TIMER_AUTODELETE; // We have mg_calloc-ed it, so autodelete + flags |= MG_TIMER_AUTODELETE; // We have alloc'ed it, so autodelete mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg); } return t; diff --git a/src/rpc.c b/src/rpc.c index 0e19ebb2..84b6c178 100644 --- a/src/rpc.c +++ b/src/rpc.c @@ -1,5 +1,6 @@ #include "rpc.h" #include "printf.h" +#include "util.h" void mg_rpc_add(struct mg_rpc **head, struct mg_str method, void (*fn)(struct mg_rpc_req *), void *fn_data) { diff --git a/src/ssi.c b/src/ssi.c index c5bd2cb5..5c2e11a1 100644 --- a/src/ssi.c +++ b/src/ssi.c @@ -1,6 +1,7 @@ #include "log.h" #include "printf.h" #include "ssi.h" +#include "util.h" #ifndef MG_MAX_SSI_DEPTH #define MG_MAX_SSI_DEPTH 5 diff --git a/src/str.c b/src/str.c index fc8f715f..75e5cd38 100644 --- a/src/str.c +++ b/src/str.c @@ -1,4 +1,5 @@ #include "str.h" +#include "util.h" struct mg_str mg_str_s(const char *s) { struct mg_str str = {(char *) s, s == NULL ? 0 : strlen(s)}; diff --git a/src/timer.c b/src/timer.c index 8253452a..6649c651 100644 --- a/src/timer.c +++ b/src/timer.c @@ -1,5 +1,6 @@ #include "arch.h" #include "timer.h" +#include "util.h" void mg_timer_init(struct mg_timer **head, struct mg_timer *t, uint64_t ms, unsigned flags, void (*fn)(void *), void *arg) { diff --git a/src/tls_mbed.c b/src/tls_mbed.c index 566010a5..707fdb31 100644 --- a/src/tls_mbed.c +++ b/src/tls_mbed.c @@ -2,6 +2,7 @@ #include "printf.h" #include "profile.h" #include "tls.h" +#include "util.h" #if MG_TLS == MG_TLS_MBED diff --git a/src/tls_openssl.c b/src/tls_openssl.c index 33b8e0ae..37838d95 100644 --- a/src/tls_openssl.c +++ b/src/tls_openssl.c @@ -1,5 +1,6 @@ #include "printf.h" #include "tls.h" +#include "util.h" #if MG_TLS == MG_TLS_OPENSSL || MG_TLS == MG_TLS_WOLFSSL diff --git a/src/tls_rsa.c b/src/tls_rsa.c index 7122dd6a..5543549a 100644 --- a/src/tls_rsa.c +++ b/src/tls_rsa.c @@ -1,5 +1,6 @@ #include "tls.h" #include "tls_rsa.h" +#include "util.h" #if MG_TLS == MG_TLS_BUILTIN @@ -320,6 +321,48 @@ NS_INTERNAL BI_CTX *bi_initialize(void) { return ctx; } +#if 0 +/** + * @brief Close the bigint context and free any resources. + * + * Free up any used memory - a check is done if all objects were not + * properly freed. + * @param ctx [in] The bigint session context. + */ +NS_INTERNAL void bi_terminate(BI_CTX *ctx) { + bi_depermanent(ctx->bi_radix); + bi_free(ctx, ctx->bi_radix); + + if (ctx->active_count != 0) { +#ifdef CONFIG_SSL_FULL_MODE + printf("bi_terminate: there were %d un-freed bigints\n", ctx->active_count); +#endif + abort(); + } + + bi_clear_cache(ctx); + mg_free(ctx); +} + +/** + *@brief Clear the memory cache. + */ +NS_INTERNAL void bi_clear_cache(BI_CTX *ctx) { + bigint *p, *pn; + + if (ctx->free_list == NULL) return; + + for (p = ctx->free_list; p != NULL; p = pn) { + pn = p->next; + mg_free(p->comps); + mg_free(p); + } + + ctx->free_count = 0; + ctx->free_list = NULL; +} +#endif + /** * @brief Increment the number of references to this object. * It does not do a full copy. diff --git a/test/unit_test.c b/test/unit_test.c index 432051aa..e11fa4af 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -1168,7 +1168,7 @@ static void test_http_server(void) { struct mg_str data = mg_file_read(&mg_fs_posix, "./data/ca.pem"); ASSERT(fetch(&mgr, buf, url, "GET /ca.pem HTTP/1.0\r\n\n") == 200); ASSERT(cmpbody(buf, data.buf) == 0); - free((void *) data.buf); + mg_free((void *) data.buf); } { @@ -1248,7 +1248,7 @@ static void test_http_server(void) { s = mg_file_read(&mg_fs_posix, "uploaded.txt"); ASSERT(s.buf != NULL); ASSERT(strcmp(s.buf, "hello\nworld") == 0); - free((void *) s.buf); + mg_free((void *) s.buf); remove("uploaded.txt"); } @@ -2112,7 +2112,7 @@ static void test_str(void) { { struct mg_str s = mg_strdup(mg_str("a")); ASSERT(mg_strcmp(s, mg_str("a")) == 0); - free((void *) s.buf); + mg_free((void *) s.buf); } { @@ -2228,11 +2228,11 @@ static void test_str(void) { p = mg_mprintf("[%s,%M,%s]", "null", pf1, 2, 3, "hi"); ASSERT(strcmp(p, "[null,5,hi]") == 0); - free(p); + mg_free(p); p = mg_mprintf("[%M,%d]", pf2, 10, 7); ASSERT(strcmp(p, "[9876543210,7]") == 0); - free(p); + mg_free(p); mg_xprintf(mg_pfn_iobuf, &io, "[%M", pf2, 10); mg_xprintf(mg_pfn_iobuf, &io, ","); @@ -2433,7 +2433,7 @@ static void test_str(void) { static void fn1(struct mg_connection *c, int ev, void *ev_data) { if (ev == MG_EV_ERROR) { - free(*(char **) c->fn_data); // See #2263 + mg_free(*(char **) c->fn_data); // See #2263 *(char **) c->fn_data = mg_mprintf("%s", (char *) ev_data); } (void) c; @@ -2454,7 +2454,7 @@ static void test_dns_error(const char *dns_server_url, const char *errstr) { mg_mgr_free(&mgr); // MG_DEBUG(("buf: [%s] [%s]", buf, errstr)); ASSERT(buf != NULL && strcmp(buf, errstr) == 0); - free(buf); + mg_free(buf); } static void test_dns(void) { @@ -2541,7 +2541,7 @@ static void test_util(void) { data = mg_file_read(&mg_fs_posix, "data.txt"); ASSERT(data.buf != NULL); ASSERT(strcmp(data.buf, "hi") == 0); - free((void *) data.buf); + mg_free((void *) data.buf); remove("data.txt"); ASSERT(mg_aton(mg_str("0"), &a) == false); ASSERT(mg_aton(mg_str("0.0.0."), &a) == false); @@ -2653,7 +2653,7 @@ static void test_util(void) { { s = mg_mprintf("%3d", 123); ASSERT(strcmp(s, "123") == 0); - free(s); + mg_free(s); } { @@ -3077,13 +3077,13 @@ static void test_packed(void) { // printf("---> %s\n", buf); ASSERT(fetch(&mgr, buf, url, "GET /Makefile HTTP/1.0\n\n") == 200); ASSERT(cmpbody(buf, data.buf) == 0); - free((void *) data.buf); + mg_free((void *) data.buf); // Load file deeper in the FS tree directly data = mg_file_read(&mg_fs_posix, "data/ssi.h"); ASSERT(fetch(&mgr, buf, url, "GET /data/ssi.h HTTP/1.0\n\n") == 200); ASSERT(cmpbody(buf, data.buf) == 0); - free((void *) data.buf); + mg_free((void *) data.buf); // List root dir ASSERT(fetch(&mgr, buf, url, "GET / HTTP/1.0\n\n") == 200); @@ -3384,14 +3384,14 @@ static void test_json(void) { ASSERT(str != NULL); // printf("---> [%s]\n", str); ASSERT(strcmp(str, "b") == 0); - free(str); + mg_free(str); json = mg_str("{\"a\": \"hi\\nthere\",\"b\": [12345, true]}"); str = mg_json_get_str(json, "$.a"); ASSERT(str != NULL); ASSERT(strcmp(str, "hi\nthere") == 0); - free(str); + mg_free(str); ASSERT(mg_json_get_long(json, "$.foo", -42) == -42); ASSERT(mg_json_get_long(json, "$.b[0]", -42) == 12345); @@ -3410,10 +3410,10 @@ static void test_json(void) { json = mg_str("[\"YWJj\", \"0100026869\"]"); ASSERT((str = mg_json_get_b64(json, "$[0]", &len)) != NULL); ASSERT(len == 3 && memcmp(str, "abc", (size_t) len) == 0); - free(str); + mg_free(str); ASSERT((str = mg_json_get_hex(json, "$[1]", &len)) != NULL); ASSERT(len == 5 && memcmp(str, "\x01\x00\x02hi", (size_t) len) == 0); - free(str); + mg_free(str); json = mg_str("{\"a\":[1,2,3], \"ab\": 2}"); ASSERT(mg_json_get_long(json, "$.a[0]", -42) == 1); diff --git a/tutorials/core/multi-threaded/main.c b/tutorials/core/multi-threaded/main.c index 6200e18e..9b421601 100644 --- a/tutorials/core/multi-threaded/main.c +++ b/tutorials/core/multi-threaded/main.c @@ -33,7 +33,7 @@ static void *thread_function(void *param) { struct thread_data *p = (struct thread_data *) param; sleep(2); // Simulate long execution mg_wakeup(p->mgr, p->conn_id, "hi!", 3); // Respond to parent - free((void *) p->message.buf); // Free all resources that were + mg_free((void *) p->message.buf); // Free all resources that were free(p); // passed to us return NULL; } diff --git a/tutorials/http/device-dashboard/net.c b/tutorials/http/device-dashboard/net.c index d47daae7..db58bb11 100644 --- a/tutorials/http/device-dashboard/net.c +++ b/tutorials/http/device-dashboard/net.c @@ -156,10 +156,10 @@ static void handle_settings_set(struct mg_connection *c, struct mg_str body) { settings.log_level = (int) mg_json_get_long(body, "$.log_level", 0); settings.brightness = mg_json_get_long(body, "$.brightness", 0); if (s && strlen(s) < MAX_DEVICE_NAME) { - free(settings.device_name); + mg_free(settings.device_name); settings.device_name = s; } else { - free(s); + mg_free(s); } s_settings = settings; // Save to the device flash mg_http_reply(c, 200, s_json_header, diff --git a/tutorials/http/uart-bridge/esp32/main/main.c b/tutorials/http/uart-bridge/esp32/main/main.c index 7efe36cf..660c8efe 100644 --- a/tutorials/http/uart-bridge/esp32/main/main.c +++ b/tutorials/http/uart-bridge/esp32/main/main.c @@ -26,9 +26,9 @@ void app_main(void) { char *ssid = mg_json_get_str(json, "$.ssid"); char *pass = mg_json_get_str(json, "$.pass"); while (!wifi_init(ssid, pass)) (void) 0; - free(ssid); - free(pass); - free((void *) json.buf); + mg_free(ssid); + mg_free(pass); + mg_free((void *) json.buf); } else { // If WiFi is not configured, run CLI until configured MG_INFO(("WiFi is not configured, running CLI. Press enter")); diff --git a/tutorials/http/uart-bridge/net.c b/tutorials/http/uart-bridge/net.c index 1a4c6cea..d7f80177 100644 --- a/tutorials/http/uart-bridge/net.c +++ b/tutorials/http/uart-bridge/net.c @@ -157,7 +157,7 @@ static void timer_fn(void *param) { static void update_string(struct mg_str json, const char *path, char **value) { char *jval; if ((jval = mg_json_get_str(json, path)) != NULL) { - free(*value); + mg_free(*value); *value = strdup(jval); } } @@ -189,7 +189,7 @@ void uart_bridge_fn(struct mg_connection *c, int ev, void *ev_data) { if (ev == MG_EV_OPEN && c->is_listening) { struct mg_str config = mg_file_read(&mg_fs_posix, "config.json"); if (config.buf != NULL) config_apply(config); - free(config.buf); + mg_free(config.buf); s_state.tcp.url = strdup(DEFAULT_TCP); s_state.websocket.url = strdup(DEFAULT_WEBSOCKET); s_state.mqtt.url = strdup(DEFAULT_MQTT); diff --git a/tutorials/http/video-stream/main.c b/tutorials/http/video-stream/main.c index 3c8b34f0..76475cd6 100644 --- a/tutorials/http/video-stream/main.c +++ b/tutorials/http/video-stream/main.c @@ -44,7 +44,7 @@ static void broadcast_mjpeg_frame(struct mg_mgr *mgr) { mg_send(c, data.buf, data.len); mg_send(c, "\r\n", 2); } - free((void *) data.buf); + mg_free((void *) data.buf); } static void timer_callback(void *arg) { diff --git a/tutorials/mqtt/mqtt-dashboard/device/net.c b/tutorials/mqtt/mqtt-dashboard/device/net.c index 6f0ccc22..82cf85ee 100644 --- a/tutorials/mqtt/mqtt-dashboard/device/net.c +++ b/tutorials/mqtt/mqtt-dashboard/device/net.c @@ -43,7 +43,7 @@ static void set_device_id(void) { struct mg_str id = mg_file_read(&mg_fs_posix, "/etc/machine-id"); if (id.buf != NULL) { mg_snprintf(buf, sizeof(buf), "%s", id.buf); - free((void *) id.buf); + mg_free((void *) id.buf); } #endif @@ -118,7 +118,7 @@ static void subscribe(struct mg_connection *c) { sub_opts.qos = s_qos; mg_mqtt_sub(c, &sub_opts); MG_INFO(("%lu SUBSCRIBED to %.*s", c->id, (int) subt.len, subt.buf)); - free(rx_topic); + mg_free(rx_topic); } static void rpc_config_set(struct mg_rpc_req *r) { @@ -169,7 +169,7 @@ static void rpc_ota_upload(struct mg_rpc_req *r) { } else { mg_rpc_ok(r, "%m", MG_ESC("ok")); } - free(buf); + mg_free(buf); } } diff --git a/tutorials/mqtt/mqtt-server/main.c b/tutorials/mqtt/mqtt-server/main.c index 5d188c27..226f34ac 100644 --- a/tutorials/mqtt/mqtt-server/main.c +++ b/tutorials/mqtt/mqtt-server/main.c @@ -78,7 +78,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) { struct mg_str topic; int num_topics = 0; while ((pos = mg_mqtt_next_sub(mm, &topic, &qos, pos)) > 0) { - struct sub *sub = calloc(1, sizeof(*sub)); + struct sub *sub = (struct sub *)calloc(1, sizeof(*sub)); sub->c = c; sub->topic = mg_strdup(topic); sub->qos = qos; @@ -128,7 +128,9 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) { next = sub->next; if (c != sub->c) continue; MG_INFO(("UNSUB %p [%.*s]", c->fd, (int) sub->topic.len, sub->topic.buf)); + mg_free(sub->topic.buf); LIST_DELETE(struct sub, &s_subs, sub); + free(sub); } } } diff --git a/tutorials/tcp/modbus-dashboard/main.c b/tutorials/tcp/modbus-dashboard/main.c index 004afbef..00136082 100644 --- a/tutorials/tcp/modbus-dashboard/main.c +++ b/tutorials/tcp/modbus-dashboard/main.c @@ -22,7 +22,7 @@ bool web_load_settings(void *buf, size_t len) { } else { memcpy(buf, data.buf, len); } - free((void *) data.buf); + mg_free((void *) data.buf); return ok; } diff --git a/tutorials/tcp/modbus-dashboard/net.c b/tutorials/tcp/modbus-dashboard/net.c index a7130ad4..8bb5c954 100644 --- a/tutorials/tcp/modbus-dashboard/net.c +++ b/tutorials/tcp/modbus-dashboard/net.c @@ -41,7 +41,7 @@ static void setfromjson(struct mg_str json, const char *jsonpath, char *buf, size_t len) { char *val = mg_json_get_str(json, jsonpath); if (val != NULL) mg_snprintf(buf, len, "%s", val); - free(val); + mg_free(val); } static void handle_settings_set(struct mg_connection *c, struct mg_str body) { @@ -159,7 +159,7 @@ static struct mg_connection *start_modbus_request(struct mg_mgr *mgr, cd->id = cid; // Store parent connection ID cd->expiration_time = mg_millis() + timeout; } - free(url); + mg_free(url); return c; } diff --git a/tutorials/tcpip/pcap-driver/main.c b/tutorials/tcpip/pcap-driver/main.c index 100cc1e9..fd8a79e2 100644 --- a/tutorials/tcpip/pcap-driver/main.c +++ b/tutorials/tcpip/pcap-driver/main.c @@ -104,7 +104,7 @@ static void fn2(struct mg_connection *c, int ev, void *ev_data) { } else if (ev == MG_EV_CONNECT) { mg_printf(c, "GET %s HTTP/1.1\r\n\r\n", mg_url_uri((char *) c->fn_data)); } else if (ev == MG_EV_CLOSE) { - free(c->fn_data); + mg_free(c->fn_data); } } diff --git a/tutorials/tcpip/tap-driver/main.c b/tutorials/tcpip/tap-driver/main.c index 008ae9a3..79e47bbb 100644 --- a/tutorials/tcpip/tap-driver/main.c +++ b/tutorials/tcpip/tap-driver/main.c @@ -48,12 +48,12 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { if (ev == MG_TCPIP_EV_ST_CHG) { MG_INFO(("State change: %u", *(uint8_t *) ev_data)); } else if (ev == MG_TCPIP_EV_DHCP_DNS) { - free(s_dns); + mg_free(s_dns); s_dns = mg_mprintf("udp://%M:53", mg_print_ip4, (uint32_t *) ev_data); ifp->mgr->dns4.url = s_dns; MG_INFO(("Set DNS to %s", ifp->mgr->dns4.url)); } else if (ev == MG_TCPIP_EV_DHCP_SNTP) { - free(s_sntp); + mg_free(s_sntp); s_sntp = mg_mprintf("udp://%M:123", mg_print_ip4, (uint32_t *) ev_data); MG_INFO(("Set SNTP to %s", s_sntp)); } @@ -128,8 +128,8 @@ int main(int argc, char *argv[]) { web_init(&mgr); while (s_signo == 0) mg_mgr_poll(&mgr, 100); // Infinite event loop - free(s_dns); - free(s_sntp); + mg_free(s_dns); + mg_free(s_sntp); mg_mgr_free(&mgr); close(fd); printf("Exiting on signal %d\n", s_signo); diff --git a/tutorials/websocket/websocket-client/main.c b/tutorials/websocket/websocket-client/main.c index a0456012..8742a5b3 100644 --- a/tutorials/websocket/websocket-client/main.c +++ b/tutorials/websocket/websocket-client/main.c @@ -9,14 +9,15 @@ static const char *s_url = "ws://localhost:8000/websocket"; static const char *s_ca_path = "ca.pem"; +static struct mg_str s_ca; // Print websocket response and signal that we're done static void fn(struct mg_connection *c, int ev, void *ev_data) { if (ev == MG_EV_OPEN) { c->is_hexdumping = 1; } else if (c->is_tls && ev == MG_EV_CONNECT) { - struct mg_str ca = mg_file_read(&mg_fs_posix, s_ca_path); - struct mg_tls_opts opts = {.ca = ca, .name = mg_url_host(s_url)}; + s_ca = mg_file_read(&mg_fs_posix, s_ca_path); + struct mg_tls_opts opts = {.ca = s_ca, .name = mg_url_host(s_url)}; mg_tls_init(c, &opts); } else if (ev == MG_EV_ERROR) { // On error, log error message @@ -32,6 +33,10 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) { if (ev == MG_EV_ERROR || ev == MG_EV_CLOSE || ev == MG_EV_WS_MSG) { *(bool *) c->fn_data = true; // Signal that we're done + if (c->is_tls) { + mg_free(s_ca.buf); + s_ca.buf = NULL; + } } } diff --git a/tutorials/websocket/websocket-server/main.c b/tutorials/websocket/websocket-server/main.c index 0420ac68..752ec4bc 100644 --- a/tutorials/websocket/websocket-server/main.c +++ b/tutorials/websocket/websocket-server/main.c @@ -10,6 +10,7 @@ static const char *s_web_root = "."; static const char *s_ca_path = "ca.pem"; static const char *s_cert_path = "cert.pem"; static const char *s_key_path = "key.pem"; +struct mg_str s_ca, s_cert, s_key; // This RESTful server implements the following endpoints: // /websocket - upgrade to Websocket, and implement websocket echo server @@ -19,15 +20,15 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) { if (ev == MG_EV_OPEN) { // c->is_hexdumping = 1; } else if(c->is_tls && ev == MG_EV_ACCEPT) { - struct mg_str ca = mg_file_read(&mg_fs_posix, s_ca_path); - struct mg_str cert = mg_file_read(&mg_fs_posix, s_cert_path); - struct mg_str key = mg_file_read(&mg_fs_posix, s_key_path); - struct mg_tls_opts opts = {.ca = ca, .cert = cert, .key = key}; + s_ca = mg_file_read(&mg_fs_posix, s_ca_path); + s_cert = mg_file_read(&mg_fs_posix, s_cert_path); + s_key = mg_file_read(&mg_fs_posix, s_key_path); + struct mg_tls_opts opts = {.ca = s_ca, .cert = s_cert, .key = s_key}; mg_tls_init(c, &opts); } else if (ev == MG_EV_HTTP_MSG) { struct mg_http_message *hm = (struct mg_http_message *) ev_data; if (mg_match(hm->uri, mg_str("/websocket"), NULL)) { - // Upgrade to websocket. From now on, a connection is a full-duplex + // Upgrade to websocket. From now on, connection is full-duplex // Websocket connection, which will receive MG_EV_WS_MSG events. mg_ws_upgrade(c, hm, NULL); } else if (mg_match(hm->uri, mg_str("/rest"), NULL)) { @@ -42,6 +43,10 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) { // Got websocket frame. Received data is wm->data. Echo it back! struct mg_ws_message *wm = (struct mg_ws_message *) ev_data; mg_ws_send(c, wm->data.buf, wm->data.len, WEBSOCKET_OP_TEXT); + } else if (ev == MG_EV_CLOSE && c->is_tls) { + mg_free(s_ca.buf); + mg_free(s_cert.buf); + mg_free(s_key.buf); } } diff --git a/tutorials/webui/webui-plain/main.c b/tutorials/webui/webui-plain/main.c index 5a6b079f..c0d6325c 100644 --- a/tutorials/webui/webui-plain/main.c +++ b/tutorials/webui/webui-plain/main.c @@ -24,8 +24,8 @@ static struct config { static void update_config(struct mg_str json, const char *path, char **value) { char *jval; if ((jval = mg_json_get_str(json, path)) != NULL) { - free(*value); - *value = strdup(jval); + mg_free(*value); + *value = jval; } } @@ -61,5 +61,8 @@ int main(void) { mg_http_listen(&mgr, s_http_addr, fn, NULL); // Create HTTP listener for (;;) mg_mgr_poll(&mgr, 1000); // Infinite event loop mg_mgr_free(&mgr); + mg_free(s_config.url); + mg_free(s_config.pub); + mg_free(s_config.sub); return 0; }