From c650fdcdfc1788eccc310b90e78c863e2f507aee Mon Sep 17 00:00:00 2001 From: Sergey Lyubka Date: Wed, 23 Feb 2022 03:06:02 +0000 Subject: [PATCH] Move mg_listen() to net.c --- docs/README.md | 4 +- mongoose.c | 99 +++++++++++++++++++++--------------------- mongoose.h | 2 + src/net.c | 39 +++++++++++++++++ src/net.h | 2 + src/sock.c | 60 +++++-------------------- test/mongoose_custom.c | 7 ++- 7 files changed, 108 insertions(+), 105 deletions(-) diff --git a/docs/README.md b/docs/README.md index cae2da72..6390e5ec 100644 --- a/docs/README.md +++ b/docs/README.md @@ -289,9 +289,7 @@ void mg_connect_resolved(struct mg_connection *c) { // implement this! } - -struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url, - mg_event_handler_t fn, void *fn_data) { +bool mg_open_listener(struct mg_connection *c, const char *url) { // implement this! } diff --git a/mongoose.c b/mongoose.c index 70f1a66b..0a2f0a28 100644 --- a/mongoose.c +++ b/mongoose.c @@ -2604,6 +2604,7 @@ struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url, + size_t mg_vprintf(struct mg_connection *c, const char *fmt, va_list ap) { char mem[256], *buf = mem; size_t len = mg_vasprintf(&buf, sizeof(mem), fmt, ap); @@ -2747,6 +2748,24 @@ struct mg_connection *mg_alloc_conn(struct mg_mgr *mgr, bool clnt, void *fd) { } return c; } + +void mg_close_conn(struct mg_connection *c) { + mg_resolve_cancel(c); // Close any pending DNS query + LIST_DELETE(struct mg_connection, &c->mgr->conns, c); + if (c == c->mgr->dns4.c) c->mgr->dns4.c = NULL; + if (c == c->mgr->dns6.c) c->mgr->dns6.c = NULL; + // Order of operations is important. `MG_EV_CLOSE` event must be fired + // before we deallocate received data, see #1331 + mg_call(c, MG_EV_CLOSE, NULL); + MG_DEBUG(("%lu closed", c->id)); + + mg_tls_free(c); + mg_iobuf_free(&c->recv); + mg_iobuf_free(&c->send); + memset(c, 0, sizeof(*c)); + free(c); +} + struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *url, mg_event_handler_t fn, void *fn_data) { struct mg_connection *c = NULL; @@ -2766,6 +2785,26 @@ struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *url, return c; } +struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url, + mg_event_handler_t fn, void *fn_data) { + struct mg_connection *c = NULL; + if ((c = mg_alloc_conn(mgr, false, NULL)) == NULL) { + MG_ERROR(("OOM %s", url)); + } else if (!mg_open_listener(c, url)) { + MG_ERROR(("Failed: %s, errno %d", url, errno)); + free(c); + } else { + c->is_listening = 1; + c->is_udp = strncmp(url, "udp:", 4) == 0; + LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c); + c->fn = fn; + c->fn_data = fn_data; + mg_call(c, MG_EV_OPEN, NULL); + MG_DEBUG(("%lu %s port %u", c->id, url, mg_ntohs(c->rem.port))); + } + return c; +} + void mg_mgr_free(struct mg_mgr *mgr) { struct mg_connection *c; for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1; @@ -3309,17 +3348,16 @@ static void mg_set_non_blocking_mode(SOCKET fd) { #endif } -static SOCKET mg_open_listener(const char *url, struct mg_addr *addr) { +bool mg_open_listener(struct mg_connection *c, const char *url) { SOCKET fd = INVALID_SOCKET; int s_err = 0; // Memoized socket error, in case closesocket() overrides it - memset(addr, 0, sizeof(*addr)); - addr->port = mg_htons(mg_url_port(url)); - if (!mg_aton(mg_url_host(url), addr)) { + c->loc.port = mg_htons(mg_url_port(url)); + if (!mg_aton(mg_url_host(url), &c->loc)) { MG_ERROR(("invalid listening URL: %s", url)); } else { union usa usa; - socklen_t slen = tousa(addr, &usa); - int on = 1, af = addr->is_ip6 ? AF_INET6 : AF_INET; + socklen_t slen = tousa(&c->loc, &usa); + int on = 1, af = c->loc.is_ip6 ? AF_INET6 : AF_INET; int type = strncmp(url, "udp:", 4) == 0 ? SOCK_DGRAM : SOCK_STREAM; int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP; (void) on; @@ -3352,9 +3390,9 @@ static SOCKET mg_open_listener(const char *url, struct mg_addr *addr) { (type == SOCK_DGRAM || listen(fd, MG_SOCK_LISTEN_BACKLOG_SIZE) == 0)) { // In case port was set to 0, get the real port number if (getsockname(fd, &usa.sa, &slen) == 0) { - addr->port = usa.sin.sin_port; + c->loc.port = usa.sin.sin_port; #if MG_ENABLE_IPV6 - if (addr->is_ip6) addr->port = usa.sin6.sin6_port; + if (c->loc.is_ip6) c->loc.port = usa.sin6.sin6_port; #endif } mg_set_non_blocking_mode(fd); @@ -3364,12 +3402,12 @@ static SOCKET mg_open_listener(const char *url, struct mg_addr *addr) { fd = INVALID_SOCKET; } } + c->fd = S2PTR(fd); if (fd == INVALID_SOCKET) { if (s_err == 0) s_err = MG_SOCK_ERRNO; MG_ERROR(("failed %s, errno %d (%s)", url, s_err, strerror(s_err))); } - - return fd; + return fd != INVALID_SOCKET; } static long mg_sock_recv(struct mg_connection *c, void *buf, size_t len) { @@ -3411,26 +3449,14 @@ static void write_conn(struct mg_connection *c) { } static void close_conn(struct mg_connection *c) { - mg_resolve_cancel(c); // Close any pending DNS query - LIST_DELETE(struct mg_connection, &c->mgr->conns, c); - if (c == c->mgr->dns4.c) c->mgr->dns4.c = NULL; - if (c == c->mgr->dns6.c) c->mgr->dns6.c = NULL; - // Order of operations is important. `MG_EV_CLOSE` event must be fired - // before we deallocate received data, see #1331 - mg_call(c, MG_EV_CLOSE, NULL); - MG_DEBUG(("%lu closed", c->id)); if (FD(c) != INVALID_SOCKET) { closesocket(FD(c)); #if MG_ARCH == MG_ARCH_FREERTOS_TCP FreeRTOS_FD_CLR(c->fd, c->mgr->ss, eSELECT_ALL); #endif - c->fd = S2PTR(INVALID_SOCKET); + c->fd = NULL; } - mg_tls_free(c); - mg_iobuf_free(&c->recv); - mg_iobuf_free(&c->send); - memset(c, 0, sizeof(*c)); - free(c); + mg_close_conn(c); } static void setsockopts(struct mg_connection *c) { @@ -3596,31 +3622,6 @@ struct mg_connection *mg_mkpipe(struct mg_mgr *mgr, mg_event_handler_t fn, return c; } -struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url, - mg_event_handler_t fn, void *fn_data) { - struct mg_connection *c = NULL; - bool is_udp = strncmp(url, "udp:", 4) == 0; - struct mg_addr addr; - SOCKET fd = mg_open_listener(url, &addr); - if (fd == INVALID_SOCKET) { - MG_ERROR(("Failed: %s, errno %d", url, MG_SOCK_ERRNO)); - } else if ((c = mg_alloc_conn(mgr, false, S2PTR(fd))) == NULL) { - MG_ERROR(("OOM %s", url)); - closesocket(fd); - } else { - memcpy(&c->loc, &addr, sizeof(struct mg_addr)); - c->fd = S2PTR(fd); - c->is_listening = 1; - c->is_udp = is_udp; - LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c); - c->fn = fn; - c->fn_data = fn_data; - mg_call(c, MG_EV_OPEN, NULL); - MG_DEBUG(("%lu %s port %u", c->id, url, mg_ntohs(c->rem.port))); - } - return c; -} - static void mg_iotest(struct mg_mgr *mgr, int ms) { #if MG_ARCH == MG_ARCH_FREERTOS_TCP struct mg_connection *c; diff --git a/mongoose.h b/mongoose.h index 159519ef..7cdba101 100644 --- a/mongoose.h +++ b/mongoose.h @@ -885,6 +885,8 @@ void mg_mgr_wakeup(struct mg_connection *pipe, const void *buf, size_t len); // These functions are used to integrate with custom network stacks struct mg_connection *mg_alloc_conn(struct mg_mgr *, bool is_client, void *fd); +void mg_close_conn(struct mg_connection *c); +bool mg_open_listener(struct mg_connection *c, const char *url); diff --git a/src/net.c b/src/net.c index e80a39be..66ad4095 100644 --- a/src/net.c +++ b/src/net.c @@ -1,6 +1,7 @@ #include "net.h" #include "dns.h" #include "log.h" +#include "tls.h" #include "util.h" size_t mg_vprintf(struct mg_connection *c, const char *fmt, va_list ap) { @@ -146,6 +147,24 @@ struct mg_connection *mg_alloc_conn(struct mg_mgr *mgr, bool clnt, void *fd) { } return c; } + +void mg_close_conn(struct mg_connection *c) { + mg_resolve_cancel(c); // Close any pending DNS query + LIST_DELETE(struct mg_connection, &c->mgr->conns, c); + if (c == c->mgr->dns4.c) c->mgr->dns4.c = NULL; + if (c == c->mgr->dns6.c) c->mgr->dns6.c = NULL; + // Order of operations is important. `MG_EV_CLOSE` event must be fired + // before we deallocate received data, see #1331 + mg_call(c, MG_EV_CLOSE, NULL); + MG_DEBUG(("%lu closed", c->id)); + + mg_tls_free(c); + mg_iobuf_free(&c->recv); + mg_iobuf_free(&c->send); + memset(c, 0, sizeof(*c)); + free(c); +} + struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *url, mg_event_handler_t fn, void *fn_data) { struct mg_connection *c = NULL; @@ -165,6 +184,26 @@ struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *url, return c; } +struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url, + mg_event_handler_t fn, void *fn_data) { + struct mg_connection *c = NULL; + if ((c = mg_alloc_conn(mgr, false, NULL)) == NULL) { + MG_ERROR(("OOM %s", url)); + } else if (!mg_open_listener(c, url)) { + MG_ERROR(("Failed: %s, errno %d", url, errno)); + free(c); + } else { + c->is_listening = 1; + c->is_udp = strncmp(url, "udp:", 4) == 0; + LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c); + c->fn = fn; + c->fn_data = fn_data; + mg_call(c, MG_EV_OPEN, NULL); + MG_DEBUG(("%lu %s port %u", c->id, url, mg_ntohs(c->rem.port))); + } + return c; +} + void mg_mgr_free(struct mg_mgr *mgr) { struct mg_connection *c; for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1; diff --git a/src/net.h b/src/net.h index b917fe76..d722d10d 100644 --- a/src/net.h +++ b/src/net.h @@ -81,3 +81,5 @@ void mg_mgr_wakeup(struct mg_connection *pipe, const void *buf, size_t len); // These functions are used to integrate with custom network stacks struct mg_connection *mg_alloc_conn(struct mg_mgr *, bool is_client, void *fd); +void mg_close_conn(struct mg_connection *c); +bool mg_open_listener(struct mg_connection *c, const char *url); diff --git a/src/sock.c b/src/sock.c index 0c913d6a..59bd8c53 100644 --- a/src/sock.c +++ b/src/sock.c @@ -180,17 +180,16 @@ static void mg_set_non_blocking_mode(SOCKET fd) { #endif } -static SOCKET mg_open_listener(const char *url, struct mg_addr *addr) { +bool mg_open_listener(struct mg_connection *c, const char *url) { SOCKET fd = INVALID_SOCKET; int s_err = 0; // Memoized socket error, in case closesocket() overrides it - memset(addr, 0, sizeof(*addr)); - addr->port = mg_htons(mg_url_port(url)); - if (!mg_aton(mg_url_host(url), addr)) { + c->loc.port = mg_htons(mg_url_port(url)); + if (!mg_aton(mg_url_host(url), &c->loc)) { MG_ERROR(("invalid listening URL: %s", url)); } else { union usa usa; - socklen_t slen = tousa(addr, &usa); - int on = 1, af = addr->is_ip6 ? AF_INET6 : AF_INET; + socklen_t slen = tousa(&c->loc, &usa); + int on = 1, af = c->loc.is_ip6 ? AF_INET6 : AF_INET; int type = strncmp(url, "udp:", 4) == 0 ? SOCK_DGRAM : SOCK_STREAM; int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP; (void) on; @@ -223,9 +222,9 @@ static SOCKET mg_open_listener(const char *url, struct mg_addr *addr) { (type == SOCK_DGRAM || listen(fd, MG_SOCK_LISTEN_BACKLOG_SIZE) == 0)) { // In case port was set to 0, get the real port number if (getsockname(fd, &usa.sa, &slen) == 0) { - addr->port = usa.sin.sin_port; + c->loc.port = usa.sin.sin_port; #if MG_ENABLE_IPV6 - if (addr->is_ip6) addr->port = usa.sin6.sin6_port; + if (c->loc.is_ip6) c->loc.port = usa.sin6.sin6_port; #endif } mg_set_non_blocking_mode(fd); @@ -235,12 +234,12 @@ static SOCKET mg_open_listener(const char *url, struct mg_addr *addr) { fd = INVALID_SOCKET; } } + c->fd = S2PTR(fd); if (fd == INVALID_SOCKET) { if (s_err == 0) s_err = MG_SOCK_ERRNO; MG_ERROR(("failed %s, errno %d (%s)", url, s_err, strerror(s_err))); } - - return fd; + return fd != INVALID_SOCKET; } static long mg_sock_recv(struct mg_connection *c, void *buf, size_t len) { @@ -282,26 +281,14 @@ static void write_conn(struct mg_connection *c) { } static void close_conn(struct mg_connection *c) { - mg_resolve_cancel(c); // Close any pending DNS query - LIST_DELETE(struct mg_connection, &c->mgr->conns, c); - if (c == c->mgr->dns4.c) c->mgr->dns4.c = NULL; - if (c == c->mgr->dns6.c) c->mgr->dns6.c = NULL; - // Order of operations is important. `MG_EV_CLOSE` event must be fired - // before we deallocate received data, see #1331 - mg_call(c, MG_EV_CLOSE, NULL); - MG_DEBUG(("%lu closed", c->id)); if (FD(c) != INVALID_SOCKET) { closesocket(FD(c)); #if MG_ARCH == MG_ARCH_FREERTOS_TCP FreeRTOS_FD_CLR(c->fd, c->mgr->ss, eSELECT_ALL); #endif - c->fd = S2PTR(INVALID_SOCKET); + c->fd = NULL; } - mg_tls_free(c); - mg_iobuf_free(&c->recv); - mg_iobuf_free(&c->send); - memset(c, 0, sizeof(*c)); - free(c); + mg_close_conn(c); } static void setsockopts(struct mg_connection *c) { @@ -467,31 +454,6 @@ struct mg_connection *mg_mkpipe(struct mg_mgr *mgr, mg_event_handler_t fn, return c; } -struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url, - mg_event_handler_t fn, void *fn_data) { - struct mg_connection *c = NULL; - bool is_udp = strncmp(url, "udp:", 4) == 0; - struct mg_addr addr; - SOCKET fd = mg_open_listener(url, &addr); - if (fd == INVALID_SOCKET) { - MG_ERROR(("Failed: %s, errno %d", url, MG_SOCK_ERRNO)); - } else if ((c = mg_alloc_conn(mgr, false, S2PTR(fd))) == NULL) { - MG_ERROR(("OOM %s", url)); - closesocket(fd); - } else { - memcpy(&c->loc, &addr, sizeof(struct mg_addr)); - c->fd = S2PTR(fd); - c->is_listening = 1; - c->is_udp = is_udp; - LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c); - c->fn = fn; - c->fn_data = fn_data; - mg_call(c, MG_EV_OPEN, NULL); - MG_DEBUG(("%lu %s port %u", c->id, url, mg_ntohs(c->rem.port))); - } - return c; -} - static void mg_iotest(struct mg_mgr *mgr, int ms) { #if MG_ARCH == MG_ARCH_FREERTOS_TCP struct mg_connection *c; diff --git a/test/mongoose_custom.c b/test/mongoose_custom.c index c3215c12..cf251571 100644 --- a/test/mongoose_custom.c +++ b/test/mongoose_custom.c @@ -9,10 +9,9 @@ void mg_connect_resolved(struct mg_connection *c) { (void) c; } -struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url, - mg_event_handler_t fn, void *fn_data) { - (void) mgr, (void) url, (void) fn, (void) fn_data; - return NULL; +bool mg_open_listener(struct mg_connection *c, const char *url) { + (void) c, (void) url; + return false; } void mg_mgr_poll(struct mg_mgr *mgr, int ms) {