MG_IO_SIZE=256 on embedded platforms

This commit is contained in:
Sergey Lyubka 2024-08-30 12:20:09 +01:00 committed by Sergio R. Caprile
parent 7923d1e930
commit 641c7d1967
11 changed files with 124 additions and 64 deletions

View File

@ -9847,7 +9847,8 @@ static void mg_tls_encrypt(struct mg_connection *c, const uint8_t *msg,
#if CHACHA20 #if CHACHA20
(void) tag; // tag is only used in aes gcm (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) { if (enc == NULL) {
mg_error(c, "TLS OOM"); mg_error(c, "TLS OOM");
return; return;
@ -9916,7 +9917,7 @@ static int mg_tls_recv_record(struct mg_connection *c) {
nonce[11] ^= (uint8_t) ((seq) &255U); nonce[11] ^= (uint8_t) ((seq) &255U);
#if CHACHA20 #if CHACHA20
{ {
uint8_t *dec = (uint8_t *) malloc(msgsz); uint8_t *dec = (uint8_t *) calloc(1, msgsz);
size_t n; size_t n;
if (dec == NULL) { if (dec == NULL) {
mg_error(c, "TLS OOM"); 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; c->is_client ? MG_TLS_STATE_CLIENT_START : MG_TLS_STATE_SERVER_START;
tls->skip_verification = opts->skip_verification; tls->skip_verification = opts->skip_verification;
tls->send.align = MG_IO_SIZE; //tls->send.align = MG_IO_SIZE;
c->tls = tls; c->tls = tls;
c->is_tls = c->is_tls_hs = 1; 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; struct tls_data *tls = (struct tls_data *) c->tls;
long n = MG_IO_WAIT; long n = MG_IO_WAIT;
if (len > MG_IO_SIZE) len = MG_IO_SIZE; 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); mg_tls_encrypt(c, (const uint8_t *) buf, len, MG_TLS_APP_DATA);
while (tls->send.len > 0 && while (tls->send.len > 0 &&
(n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) { (n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) {

View File

@ -179,10 +179,6 @@ extern "C" {
#include <FreeRTOS.h> #include <FreeRTOS.h>
#include <task.h> #include <task.h>
#ifndef MG_IO_SIZE
#define MG_IO_SIZE 512
#endif
#define calloc(a, b) mg_calloc(a, b) #define calloc(a, b) mg_calloc(a, b)
#define free(a) vPortFree(a) #define free(a) vPortFree(a)
#define malloc(a) pvPortMalloc(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 #define MG_ENABLE_POSIX_FS 1
#endif #endif
#ifndef MG_IO_SIZE
#define MG_IO_SIZE 16384
#endif
#endif #endif
@ -507,6 +507,10 @@ typedef int socklen_t;
#define MG_ENABLE_POSIX_FS 1 #define MG_ENABLE_POSIX_FS 1
#endif #endif
#ifndef MG_IO_SIZE
#define MG_IO_SIZE 16384
#endif
#endif #endif
@ -754,7 +758,7 @@ struct timeval {
#endif #endif
#ifndef MG_IO_SIZE #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 #endif
#ifndef MG_MAX_RECV_SIZE #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 #if defined(MG_ENABLE_TCPIP) && MG_ENABLE_TCPIP
struct mg_tcpip_if; // Mongoose TCP/IP network interface struct mg_tcpip_if; // Mongoose TCP/IP network interface
#define MG_TCPIP_IFACE(mgr_) ((struct mg_tcpip_if *) (mgr_)->priv)
struct mg_tcpip_driver { struct mg_tcpip_driver {
bool (*init)(struct mg_tcpip_if *); // Init driver bool (*init)(struct mg_tcpip_if *); // Init driver
@ -3074,46 +3079,6 @@ struct mg_tcpip_driver_tm4c_data {
#endif #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 #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC) && MG_ENABLE_DRIVER_XMC
struct mg_tcpip_driver_xmc_data { struct mg_tcpip_driver_xmc_data {
@ -3160,6 +3125,41 @@ struct mg_tcpip_driver_xmc_data {
#endif #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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -25,10 +25,6 @@
#include <FreeRTOS.h> #include <FreeRTOS.h>
#include <task.h> #include <task.h>
#ifndef MG_IO_SIZE
#define MG_IO_SIZE 512
#endif
#define calloc(a, b) mg_calloc(a, b) #define calloc(a, b) mg_calloc(a, b)
#define free(a) vPortFree(a) #define free(a) vPortFree(a)
#define malloc(a) pvPortMalloc(a) #define malloc(a) pvPortMalloc(a)

View File

@ -60,4 +60,8 @@
#define MG_ENABLE_POSIX_FS 1 #define MG_ENABLE_POSIX_FS 1
#endif #endif
#ifndef MG_IO_SIZE
#define MG_IO_SIZE 16384
#endif
#endif #endif

View File

@ -114,4 +114,8 @@ typedef int socklen_t;
#define MG_ENABLE_POSIX_FS 1 #define MG_ENABLE_POSIX_FS 1
#endif #endif
#ifndef MG_IO_SIZE
#define MG_IO_SIZE 16384
#endif
#endif #endif

View File

@ -82,7 +82,7 @@
#endif #endif
#ifndef MG_IO_SIZE #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 #endif
#ifndef MG_MAX_RECV_SIZE #ifndef MG_MAX_RECV_SIZE

View File

@ -404,7 +404,8 @@ static void mg_tls_encrypt(struct mg_connection *c, const uint8_t *msg,
#if CHACHA20 #if CHACHA20
(void) tag; // tag is only used in aes gcm (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) { if (enc == NULL) {
mg_error(c, "TLS OOM"); mg_error(c, "TLS OOM");
return; return;
@ -473,7 +474,7 @@ static int mg_tls_recv_record(struct mg_connection *c) {
nonce[11] ^= (uint8_t) ((seq) &255U); nonce[11] ^= (uint8_t) ((seq) &255U);
#if CHACHA20 #if CHACHA20
{ {
uint8_t *dec = (uint8_t *) malloc(msgsz); uint8_t *dec = (uint8_t *) calloc(1, msgsz);
size_t n; size_t n;
if (dec == NULL) { if (dec == NULL) {
mg_error(c, "TLS OOM"); 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; c->is_client ? MG_TLS_STATE_CLIENT_START : MG_TLS_STATE_SERVER_START;
tls->skip_verification = opts->skip_verification; tls->skip_verification = opts->skip_verification;
tls->send.align = MG_IO_SIZE; //tls->send.align = MG_IO_SIZE;
c->tls = tls; c->tls = tls;
c->is_tls = c->is_tls_hs = 1; 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; struct tls_data *tls = (struct tls_data *) c->tls;
long n = MG_IO_WAIT; long n = MG_IO_WAIT;
if (len > MG_IO_SIZE) len = MG_IO_SIZE; 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); mg_tls_encrypt(c, (const uint8_t *) buf, len, MG_TLS_APP_DATA);
while (tls->send.len > 0 && while (tls->send.len > 0 &&
(n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) { (n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) {

View File

@ -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 CFLAGS = -W -Wall -Wextra -g -I. # Build options
# Mongoose build options. See https://mongoose.ws/documentation/#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 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 PROG ?= example.exe # Use .exe suffix for the binary

View File

@ -2556,7 +2556,7 @@ static const struct packed_file {
size_t size; size_t size;
time_t mtime; time_t mtime;
} packed_files[] = { } packed_files[] = {
{"/certs/ca.pem", v1, sizeof(v1), 1713395242}, {"/certs/ca.pem", v1, sizeof(v1), 1696845443},
{NULL, NULL, 0, 0} {NULL, NULL, 0, 0}
}; };

View File

@ -3,10 +3,12 @@ DELETE = rm -rf # Command to remove files
OUT ?= -o $(PROG) # Compiler argument for output file OUT ?= -o $(PROG) # Compiler argument for output file
SOURCES = main.c mongoose.c # Source code files SOURCES = main.c mongoose.c # Source code files
CFLAGS = -W -Wall -Wextra -g -I. # Build options CFLAGS = -W -Wall -Wextra -g -I. # Build options
CFLAGS += -fsanitize=address,undefined,alignment
# Mongoose build options. See https://mongoose.ws/documentation/#build-options # 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_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_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 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 PROG ?= example.exe # Use .exe suffix for the binary

View File

@ -6,11 +6,43 @@
static int s_debug_level = MG_LL_INFO; static int s_debug_level = MG_LL_INFO;
static const char *s_root_dir = "."; 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_enable_hexdump = "no";
static const char *s_ssi_pattern = "#.html"; static const char *s_ssi_pattern = "#.html";
static const char *s_upload_dir = NULL; // File uploads disabled by default 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 // Handle interrupts, like Ctrl-C
static int s_signo; static int s_signo;
static void signal_handler(int signo) { static void signal_handler(int signo) {
@ -20,6 +52,16 @@ static void signal_handler(int signo) {
// Event handler for the listening connection. // Event handler for the listening connection.
// Simply serve static files from `s_root_dir` // Simply serve static files from `s_root_dir`
static void cb(struct mg_connection *c, int ev, void *ev_data) { 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) { if (ev == MG_EV_HTTP_MSG) {
struct mg_http_message *hm = ev_data; 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" " -u DIR - file upload directory, default: unset\n"
" -v LEVEL - debug level, from 0 to 4, default: %d\n", " -v LEVEL - debug level, from 0 to 4, default: %d\n",
MG_VERSION, prog, s_enable_hexdump, s_ssi_pattern, s_root_dir, 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); exit(EXIT_FAILURE);
} }
@ -93,7 +135,9 @@ int main(int argc, char *argv[]) {
} else if (strcmp(argv[i], "-S") == 0) { } else if (strcmp(argv[i], "-S") == 0) {
s_ssi_pattern = argv[++i]; s_ssi_pattern = argv[++i];
} else if (strcmp(argv[i], "-l") == 0) { } 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) { } else if (strcmp(argv[i], "-u") == 0) {
s_upload_dir = argv[++i]; s_upload_dir = argv[++i];
} else if (strcmp(argv[i], "-v") == 0) { } else if (strcmp(argv[i], "-v") == 0) {
@ -115,16 +159,22 @@ int main(int argc, char *argv[]) {
signal(SIGTERM, signal_handler); signal(SIGTERM, signal_handler);
mg_log_set(s_debug_level); mg_log_set(s_debug_level);
mg_mgr_init(&mgr); 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", 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); exit(EXIT_FAILURE);
} }
if (mg_casecmp(s_enable_hexdump, "yes") == 0) c->is_hexdumping = 1; if (mg_casecmp(s_enable_hexdump, "yes") == 0) c->is_hexdumping = 1;
// Start infinite event loop // Start infinite event loop
MG_INFO(("Mongoose version : v%s", MG_VERSION)); 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(("Web root : [%s]", s_root_dir));
MG_INFO(("Upload dir : [%s]", s_upload_dir ? s_upload_dir : "unset")); MG_INFO(("Upload dir : [%s]", s_upload_dir ? s_upload_dir : "unset"));
while (s_signo == 0) mg_mgr_poll(&mgr, 1000); while (s_signo == 0) mg_mgr_poll(&mgr, 1000);