mirror of
https://github.com/cesanta/mongoose.git
synced 2025-01-14 01:38:01 +08:00
Move mg_listen() to net.c
This commit is contained in:
parent
e99973d4b7
commit
c650fdcdfc
@ -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!
|
||||
}
|
||||
|
||||
|
99
mongoose.c
99
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;
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
||||
|
39
src/net.c
39
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;
|
||||
|
@ -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);
|
||||
|
60
src/sock.c
60
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;
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user