diff --git a/mongoose.c b/mongoose.c index e9592aa2..cf0eb4be 100644 --- a/mongoose.c +++ b/mongoose.c @@ -9847,7 +9847,8 @@ static void mg_tls_encrypt(struct mg_connection *c, const uint8_t *msg, #if CHACHA20 (void) tag; // tag is only used in aes gcm { - uint8_t *enc = (uint8_t *) malloc(8192); + size_t maxlen = MG_IO_SIZE > 16384 ? 16384 : MG_IO_SIZE; + uint8_t *enc = (uint8_t *) calloc(1, maxlen + 256 + 1); if (enc == NULL) { mg_error(c, "TLS OOM"); return; @@ -9916,7 +9917,7 @@ static int mg_tls_recv_record(struct mg_connection *c) { nonce[11] ^= (uint8_t) ((seq) &255U); #if CHACHA20 { - uint8_t *dec = (uint8_t *) malloc(msgsz); + uint8_t *dec = (uint8_t *) calloc(1, msgsz); size_t n; if (dec == NULL) { mg_error(c, "TLS OOM"); @@ -10732,7 +10733,7 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { c->is_client ? MG_TLS_STATE_CLIENT_START : MG_TLS_STATE_SERVER_START; tls->skip_verification = opts->skip_verification; - tls->send.align = MG_IO_SIZE; + //tls->send.align = MG_IO_SIZE; c->tls = tls; c->is_tls = c->is_tls_hs = 1; @@ -10802,6 +10803,7 @@ long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) { struct tls_data *tls = (struct tls_data *) c->tls; long n = MG_IO_WAIT; if (len > MG_IO_SIZE) len = MG_IO_SIZE; + if (len > 16384) len = 16384; mg_tls_encrypt(c, (const uint8_t *) buf, len, MG_TLS_APP_DATA); while (tls->send.len > 0 && (n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) { diff --git a/mongoose.h b/mongoose.h index de6898ef..1cc3d837 100644 --- a/mongoose.h +++ b/mongoose.h @@ -179,10 +179,6 @@ extern "C" { #include #include -#ifndef MG_IO_SIZE -#define MG_IO_SIZE 512 -#endif - #define calloc(a, b) mg_calloc(a, b) #define free(a) vPortFree(a) #define malloc(a) pvPortMalloc(a) @@ -390,6 +386,10 @@ static inline int mg_mkdir(const char *path, mode_t mode) { #define MG_ENABLE_POSIX_FS 1 #endif +#ifndef MG_IO_SIZE +#define MG_IO_SIZE 16384 +#endif + #endif @@ -507,6 +507,10 @@ typedef int socklen_t; #define MG_ENABLE_POSIX_FS 1 #endif +#ifndef MG_IO_SIZE +#define MG_IO_SIZE 16384 +#endif + #endif @@ -754,7 +758,7 @@ struct timeval { #endif #ifndef MG_IO_SIZE -#define MG_IO_SIZE 2048 // Granularity of the send/recv IO buffer growth +#define MG_IO_SIZE 256 // Granularity of the send/recv IO buffer growth #endif #ifndef MG_MAX_RECV_SIZE @@ -2679,6 +2683,7 @@ void mg_device_reset(void); // Reboot device immediately #if defined(MG_ENABLE_TCPIP) && MG_ENABLE_TCPIP struct mg_tcpip_if; // Mongoose TCP/IP network interface +#define MG_TCPIP_IFACE(mgr_) ((struct mg_tcpip_if *) (mgr_)->priv) struct mg_tcpip_driver { bool (*init)(struct mg_tcpip_if *); // Init driver @@ -3074,46 +3079,6 @@ struct mg_tcpip_driver_tm4c_data { #endif -#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_W5500) && MG_ENABLE_DRIVER_W5500 - -#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 - - - #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC) && MG_ENABLE_DRIVER_XMC struct mg_tcpip_driver_xmc_data { @@ -3160,6 +3125,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 e3d81bd7..a55f59db 100644 --- a/src/arch_freertos.h +++ b/src/arch_freertos.h @@ -25,10 +25,6 @@ #include #include -#ifndef MG_IO_SIZE -#define MG_IO_SIZE 512 -#endif - #define calloc(a, b) mg_calloc(a, b) #define free(a) vPortFree(a) #define malloc(a) pvPortMalloc(a) diff --git a/src/arch_unix.h b/src/arch_unix.h index ea76e3b4..1ea9fd51 100644 --- a/src/arch_unix.h +++ b/src/arch_unix.h @@ -60,4 +60,8 @@ #define MG_ENABLE_POSIX_FS 1 #endif +#ifndef MG_IO_SIZE +#define MG_IO_SIZE 16384 +#endif + #endif diff --git a/src/arch_win32.h b/src/arch_win32.h index 2f9a7074..b0ab1b69 100644 --- a/src/arch_win32.h +++ b/src/arch_win32.h @@ -114,4 +114,8 @@ typedef int socklen_t; #define MG_ENABLE_POSIX_FS 1 #endif +#ifndef MG_IO_SIZE +#define MG_IO_SIZE 16384 +#endif + #endif diff --git a/src/config.h b/src/config.h index 37e6c54d..b91cf450 100644 --- a/src/config.h +++ b/src/config.h @@ -82,7 +82,7 @@ #endif #ifndef MG_IO_SIZE -#define MG_IO_SIZE 2048 // Granularity of the send/recv IO buffer growth +#define MG_IO_SIZE 256 // Granularity of the send/recv IO buffer growth #endif #ifndef MG_MAX_RECV_SIZE diff --git a/src/tls_builtin.c b/src/tls_builtin.c index 6be8105c..d96d4b39 100644 --- a/src/tls_builtin.c +++ b/src/tls_builtin.c @@ -404,7 +404,8 @@ static void mg_tls_encrypt(struct mg_connection *c, const uint8_t *msg, #if CHACHA20 (void) tag; // tag is only used in aes gcm { - uint8_t *enc = (uint8_t *) malloc(8192); + size_t maxlen = MG_IO_SIZE > 16384 ? 16384 : MG_IO_SIZE; + uint8_t *enc = (uint8_t *) calloc(1, maxlen + 256 + 1); if (enc == NULL) { mg_error(c, "TLS OOM"); return; @@ -473,7 +474,7 @@ static int mg_tls_recv_record(struct mg_connection *c) { nonce[11] ^= (uint8_t) ((seq) &255U); #if CHACHA20 { - uint8_t *dec = (uint8_t *) malloc(msgsz); + uint8_t *dec = (uint8_t *) calloc(1, msgsz); size_t n; if (dec == NULL) { mg_error(c, "TLS OOM"); @@ -1289,7 +1290,7 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { c->is_client ? MG_TLS_STATE_CLIENT_START : MG_TLS_STATE_SERVER_START; tls->skip_verification = opts->skip_verification; - tls->send.align = MG_IO_SIZE; + //tls->send.align = MG_IO_SIZE; c->tls = tls; c->is_tls = c->is_tls_hs = 1; @@ -1359,6 +1360,7 @@ long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) { struct tls_data *tls = (struct tls_data *) c->tls; long n = MG_IO_WAIT; if (len > MG_IO_SIZE) len = MG_IO_SIZE; + if (len > 16384) len = 16384; mg_tls_encrypt(c, (const uint8_t *) buf, len, MG_TLS_APP_DATA); while (tls->send.len > 0 && (n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) { diff --git a/tutorials/http/http-client/Makefile b/tutorials/http/http-client/Makefile index a052361f..05606d7a 100644 --- a/tutorials/http/http-client/Makefile +++ b/tutorials/http/http-client/Makefile @@ -6,7 +6,7 @@ SOURCES = main.c mongoose.c packed_fs.c # Source code files, packed_fs.c c CFLAGS = -W -Wall -Wextra -g -I. # Build options # Mongoose build options. See https://mongoose.ws/documentation/#build-options -CFLAGS_MONGOOSE += -DMG_ENABLE_LINES=1 -DMG_ENABLE_PACKED_FS=1 +CFLAGS_MONGOOSE += -DMG_ENABLE_LINES=1 -DMG_ENABLE_PACKED_FS=1 -DMG_TLS=MG_TLS_BUILTIN ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe PROG ?= example.exe # Use .exe suffix for the binary diff --git a/tutorials/http/http-client/packed_fs.c b/tutorials/http/http-client/packed_fs.c index 7796ec8a..a54b0a04 100644 --- a/tutorials/http/http-client/packed_fs.c +++ b/tutorials/http/http-client/packed_fs.c @@ -2556,7 +2556,7 @@ static const struct packed_file { size_t size; time_t mtime; } packed_files[] = { - {"/certs/ca.pem", v1, sizeof(v1), 1713395242}, + {"/certs/ca.pem", v1, sizeof(v1), 1696845443}, {NULL, NULL, 0, 0} }; diff --git a/tutorials/http/http-server/Makefile b/tutorials/http/http-server/Makefile index aad919a9..43098952 100644 --- a/tutorials/http/http-server/Makefile +++ b/tutorials/http/http-server/Makefile @@ -3,10 +3,12 @@ DELETE = rm -rf # Command to remove files OUT ?= -o $(PROG) # Compiler argument for output file SOURCES = main.c mongoose.c # Source code files CFLAGS = -W -Wall -Wextra -g -I. # Build options +CFLAGS += -fsanitize=address,undefined,alignment # Mongoose build options. See https://mongoose.ws/documentation/#build-options CFLAGS_MONGOOSE += -DMG_HTTP_DIRLIST_TIME_FMT="%Y/%m/%d %H:%M:%S" CFLAGS_MONGOOSE += -DMG_ENABLE_LINES=1 -DMG_ENABLE_IPV6=1 -DMG_ENABLE_SSI=1 +CFLAGS_MONGOOSE += -DMG_TLS=MG_TLS_BUILTIN ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe PROG ?= example.exe # Use .exe suffix for the binary diff --git a/tutorials/http/http-server/main.c b/tutorials/http/http-server/main.c index cf170f86..8ad3fd9b 100644 --- a/tutorials/http/http-server/main.c +++ b/tutorials/http/http-server/main.c @@ -6,11 +6,43 @@ static int s_debug_level = MG_LL_INFO; static const char *s_root_dir = "."; -static const char *s_listening_address = "http://0.0.0.0:8000"; +static const char *s_addr1 = "http://0.0.0.0:8000"; +static const char *s_addr2 = "https://0.0.0.0:8443"; static const char *s_enable_hexdump = "no"; static const char *s_ssi_pattern = "#.html"; static const char *s_upload_dir = NULL; // File uploads disabled by default +// Self signed certificates, see +// https://github.com/cesanta/mongoose/blob/master/test/certs/generate.sh +#ifdef TLS_TWOWAY +static const char *s_tls_ca = + "-----BEGIN CERTIFICATE-----\n" + "MIIBFTCBvAIJAMNTFtpfcq8NMAoGCCqGSM49BAMCMBMxETAPBgNVBAMMCE1vbmdv\n" + "b3NlMB4XDTI0MDUwNzE0MzczNloXDTM0MDUwNTE0MzczNlowEzERMA8GA1UEAwwI\n" + "TW9uZ29vc2UwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASuP+86T/rOWnGpEVhl\n" + "fxYZ+pjMbCmDZ+vdnP0rjoxudwRMRQCv5slRlDK7Lxue761sdvqxWr0Ma6TFGTNg\n" + "epsRMAoGCCqGSM49BAMCA0gAMEUCIQCwb2CxuAKm51s81S6BIoy1IcandXSohnqs\n" + "us64BAA7QgIgGGtUrpkgFSS0oPBlCUG6YPHFVw42vTfpTC0ySwAS0M4=\n" + "-----END CERTIFICATE-----\n"; +#endif +static const char *s_tls_cert = + "-----BEGIN CERTIFICATE-----\n" + "MIIBMTCB2aADAgECAgkAluqkgeuV/zUwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwI\n" + "TW9uZ29vc2UwHhcNMjQwNTA3MTQzNzM2WhcNMzQwNTA1MTQzNzM2WjARMQ8wDQYD\n" + "VQQDDAZzZXJ2ZXIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASo3oEiG+BuTt5y\n" + "ZRyfwNr0C+SP+4M0RG2pYkb2v+ivbpfi72NHkmXiF/kbHXtgmSrn/PeTqiA8M+mg\n" + "BhYjDX+zoxgwFjAUBgNVHREEDTALgglsb2NhbGhvc3QwCgYIKoZIzj0EAwIDRwAw\n" + "RAIgTXW9MITQSwzqbNTxUUdt9DcB+8pPUTbWZpiXcA26GMYCIBiYw+DSFMLHmkHF\n" + "+5U3NXW3gVCLN9ntD5DAx8LTG8sB\n" + "-----END CERTIFICATE-----\n"; + +static const char *s_tls_key = + "-----BEGIN EC PRIVATE KEY-----\n" + "MHcCAQEEIAVdo8UAScxG7jiuNY2UZESNX/KPH8qJ0u0gOMMsAzYWoAoGCCqGSM49\n" + "AwEHoUQDQgAEqN6BIhvgbk7ecmUcn8Da9Avkj/uDNERtqWJG9r/or26X4u9jR5Jl\n" + "4hf5Gx17YJkq5/z3k6ogPDPpoAYWIw1/sw==\n" + "-----END EC PRIVATE KEY-----\n"; + // Handle interrupts, like Ctrl-C static int s_signo; static void signal_handler(int signo) { @@ -20,6 +52,16 @@ static void signal_handler(int signo) { // Event handler for the listening connection. // Simply serve static files from `s_root_dir` static void cb(struct mg_connection *c, int ev, void *ev_data) { + if (ev == MG_EV_ACCEPT && c->fn_data != NULL) { + struct mg_tls_opts opts; + memset(&opts, 0, sizeof(opts)); +#ifdef TLS_TWOWAY + opts.ca = mg_str(s_tls_ca); +#endif + opts.cert = mg_str(s_tls_cert); + opts.key = mg_str(s_tls_key); + mg_tls_init(c, &opts); + } if (ev == MG_EV_HTTP_MSG) { struct mg_http_message *hm = ev_data; @@ -74,7 +116,7 @@ static void usage(const char *prog) { " -u DIR - file upload directory, default: unset\n" " -v LEVEL - debug level, from 0 to 4, default: %d\n", MG_VERSION, prog, s_enable_hexdump, s_ssi_pattern, s_root_dir, - s_listening_address, s_debug_level); + s_addr1, s_debug_level); exit(EXIT_FAILURE); } @@ -93,7 +135,9 @@ int main(int argc, char *argv[]) { } else if (strcmp(argv[i], "-S") == 0) { s_ssi_pattern = argv[++i]; } else if (strcmp(argv[i], "-l") == 0) { - s_listening_address = argv[++i]; + s_addr1 = argv[++i]; + } else if (strcmp(argv[i], "-l2") == 0) { + s_addr2 = argv[++i]; } else if (strcmp(argv[i], "-u") == 0) { s_upload_dir = argv[++i]; } else if (strcmp(argv[i], "-v") == 0) { @@ -115,16 +159,22 @@ int main(int argc, char *argv[]) { signal(SIGTERM, signal_handler); mg_log_set(s_debug_level); mg_mgr_init(&mgr); - if ((c = mg_http_listen(&mgr, s_listening_address, cb, &mgr)) == NULL) { + if ((c = mg_http_listen(&mgr, s_addr1, cb, NULL)) == NULL) { MG_ERROR(("Cannot listen on %s. Use http://ADDR:PORT or :PORT", - s_listening_address)); + s_addr1)); + exit(EXIT_FAILURE); + } + if ((c = mg_http_listen(&mgr, s_addr2, cb, (void *) 1)) == NULL) { + MG_ERROR(("Cannot listen on %s. Use http://ADDR:PORT or :PORT", + s_addr2)); exit(EXIT_FAILURE); } if (mg_casecmp(s_enable_hexdump, "yes") == 0) c->is_hexdumping = 1; // Start infinite event loop MG_INFO(("Mongoose version : v%s", MG_VERSION)); - MG_INFO(("Listening on : %s", s_listening_address)); + MG_INFO(("HTTP listener : %s", s_addr1)); + MG_INFO(("HTTPS listener : %s", s_addr2)); MG_INFO(("Web root : [%s]", s_root_dir)); MG_INFO(("Upload dir : [%s]", s_upload_dir ? s_upload_dir : "unset")); while (s_signo == 0) mg_mgr_poll(&mgr, 1000);