mirror of
https://github.com/cesanta/mongoose.git
synced 2026-11-10 16:31:44 +00:00
Refactor mg_open_listener()
This commit is contained in:
1 parent
84480f4072
commit
5ac5c93c90
2 files changed
+68
-68
No files matched your search
+34
-34
@@ -3322,7 +3322,7 @@ static void mg_set_non_blocking_mode(SOCKET fd) {
|
|||||||
|
|
||||||
bool mg_open_listener(struct mg_connection *c, const char *url) {
|
bool mg_open_listener(struct mg_connection *c, const char *url) {
|
||||||
SOCKET fd = INVALID_SOCKET;
|
SOCKET fd = INVALID_SOCKET;
|
||||||
int s_err = 0; // Memoized socket error, in case closesocket() overrides it
|
bool success = false;
|
||||||
c->loc.port = mg_htons(mg_url_port(url));
|
c->loc.port = mg_htons(mg_url_port(url));
|
||||||
if (!mg_aton(mg_url_host(url), &c->loc)) {
|
if (!mg_aton(mg_url_host(url), &c->loc)) {
|
||||||
MG_ERROR(("invalid listening URL: %s", url));
|
MG_ERROR(("invalid listening URL: %s", url));
|
||||||
@@ -3334,47 +3334,47 @@ bool mg_open_listener(struct mg_connection *c, const char *url) {
|
|||||||
int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
|
int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
|
||||||
(void) on;
|
(void) on;
|
||||||
|
|
||||||
if ((fd = socket(af, type, proto)) != INVALID_SOCKET &&
|
if ((fd = socket(af, type, proto)) == INVALID_SOCKET) {
|
||||||
|
MG_ERROR(("socket: %s", MG_SOCK_ERRNO));
|
||||||
#if (MG_ARCH != MG_ARCH_WIN32 || !defined(SO_EXCLUSIVEADDRUSE)) && \
|
#if (MG_ARCH != MG_ARCH_WIN32 || !defined(SO_EXCLUSIVEADDRUSE)) && \
|
||||||
(!defined(LWIP_SOCKET) || (defined(LWIP_SOCKET) && SO_REUSE == 1))
|
(!defined(LWIP_SOCKET) || (defined(LWIP_SOCKET) && SO_REUSE == 1))
|
||||||
// 1. SO_RESUSEADDR is not enabled on Windows because the semantics of
|
} else if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on,
|
||||||
// SO_REUSEADDR on UNIX and Windows is different. On Windows,
|
sizeof(on)) != 0) {
|
||||||
// SO_REUSEADDR allows to bind a socket to a port without error even
|
// 1. SO_RESUSEADDR is not enabled on Windows because the semantics of
|
||||||
// if the port is already open by another program. This is not the
|
// SO_REUSEADDR on UNIX and Windows is different. On Windows,
|
||||||
// behavior SO_REUSEADDR was designed for, and leads to hard-to-track
|
// SO_REUSEADDR allows to bind a socket to a port without error even
|
||||||
// failure scenarios. Therefore, SO_REUSEADDR was disabled on Windows
|
// if the port is already open by another program. This is not the
|
||||||
// unless SO_EXCLUSIVEADDRUSE is supported and set on a socket.
|
// behavior SO_REUSEADDR was designed for, and leads to hard-to-track
|
||||||
// 2. In case of LWIP, SO_REUSEADDR should be explicitly enabled, by
|
// failure scenarios. Therefore, SO_REUSEADDR was disabled on Windows
|
||||||
// defining
|
// unless SO_EXCLUSIVEADDRUSE is supported and set on a socket.
|
||||||
// SO_REUSE (in lwipopts.h), otherwise the code below will compile
|
// 2. In case of LWIP, SO_REUSEADDR should be explicitly enabled, by
|
||||||
// but won't work! (setsockopt will return EINVAL)
|
// defining
|
||||||
!setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) &&
|
// SO_REUSE (in lwipopts.h), otherwise the code below will compile
|
||||||
|
// but won't work! (setsockopt will return EINVAL)
|
||||||
|
MG_ERROR(("reuseaddr: %s", MG_SOCK_ERRNO));
|
||||||
#endif
|
#endif
|
||||||
#if MG_ARCH == MG_ARCH_WIN32 && defined(SO_EXCLUSIVEADDRUSE) && !defined(WINCE)
|
#if MG_ARCH == MG_ARCH_WIN32 && defined(SO_EXCLUSIVEADDRUSE) && !defined(WINCE)
|
||||||
// "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE"
|
} else if (setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *) &on,
|
||||||
//! setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char *) &on, sizeof(on))
|
sizeof(on)) != 0) {
|
||||||
//! &&
|
// "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE"
|
||||||
!setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *) &on,
|
MG_ERROR(("exclusiveaddruse: %s", MG_SOCK_ERRNO));
|
||||||
sizeof(on)) &&
|
|
||||||
#endif
|
#endif
|
||||||
bind(fd, &usa.sa, slen) == 0 &&
|
} else if (bind(fd, &usa.sa, slen) != 0) {
|
||||||
// NOTE(lsm): FreeRTOS uses backlog value as a connection limit
|
MG_ERROR(("bind: %s", MG_SOCK_ERRNO));
|
||||||
(type == SOCK_DGRAM || listen(fd, MG_SOCK_LISTEN_BACKLOG_SIZE) == 0)) {
|
} else if ((type == SOCK_STREAM &&
|
||||||
|
listen(fd, MG_SOCK_LISTEN_BACKLOG_SIZE) != 0)) {
|
||||||
|
// NOTE(lsm): FreeRTOS uses backlog value as a connection limit
|
||||||
// In case port was set to 0, get the real port number
|
// In case port was set to 0, get the real port number
|
||||||
|
MG_ERROR(("listen: %s", MG_SOCK_ERRNO));
|
||||||
|
} else {
|
||||||
setlocaddr(fd, &c->loc);
|
setlocaddr(fd, &c->loc);
|
||||||
mg_set_non_blocking_mode(fd);
|
mg_set_non_blocking_mode(fd);
|
||||||
} else if (fd != INVALID_SOCKET) {
|
c->fd = S2PTR(fd);
|
||||||
s_err = MG_SOCK_ERRNO;
|
success = true;
|
||||||
closesocket(fd);
|
|
||||||
fd = INVALID_SOCKET;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c->fd = S2PTR(fd);
|
if (success == false && fd != INVALID_SOCKET) closesocket(fd);
|
||||||
if (fd == INVALID_SOCKET) {
|
return success;
|
||||||
if (s_err == 0) s_err = MG_SOCK_ERRNO;
|
|
||||||
MG_ERROR(("failed %s, errno %d (%s)", url, s_err, strerror(s_err)));
|
|
||||||
}
|
|
||||||
return fd != INVALID_SOCKET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static long mg_sock_recv(struct mg_connection *c, void *buf, size_t len) {
|
static long mg_sock_recv(struct mg_connection *c, void *buf, size_t len) {
|
||||||
@@ -3512,8 +3512,8 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
|
|||||||
if (fd == INVALID_SOCKET) {
|
if (fd == INVALID_SOCKET) {
|
||||||
#if MG_ARCH == MG_ARCH_AZURERTOS
|
#if MG_ARCH == MG_ARCH_AZURERTOS
|
||||||
// AzureRTOS, in non-block socket mode can mark listening socket readable
|
// AzureRTOS, in non-block socket mode can mark listening socket readable
|
||||||
// even it is not. See comment for 'select' func implementation in nx_bsd.c
|
// even it is not. See comment for 'select' func implementation in
|
||||||
// That's not an error, just should try later
|
// nx_bsd.c That's not an error, just should try later
|
||||||
if (MG_SOCK_ERRNO != EAGAIN)
|
if (MG_SOCK_ERRNO != EAGAIN)
|
||||||
#endif
|
#endif
|
||||||
MG_ERROR(("%lu accept failed, errno %d", lsn->id, MG_SOCK_ERRNO));
|
MG_ERROR(("%lu accept failed, errno %d", lsn->id, MG_SOCK_ERRNO));
|
||||||
|
|||||||
+34
-34
@@ -185,7 +185,7 @@ static void mg_set_non_blocking_mode(SOCKET fd) {
|
|||||||
|
|
||||||
bool mg_open_listener(struct mg_connection *c, const char *url) {
|
bool mg_open_listener(struct mg_connection *c, const char *url) {
|
||||||
SOCKET fd = INVALID_SOCKET;
|
SOCKET fd = INVALID_SOCKET;
|
||||||
int s_err = 0; // Memoized socket error, in case closesocket() overrides it
|
bool success = false;
|
||||||
c->loc.port = mg_htons(mg_url_port(url));
|
c->loc.port = mg_htons(mg_url_port(url));
|
||||||
if (!mg_aton(mg_url_host(url), &c->loc)) {
|
if (!mg_aton(mg_url_host(url), &c->loc)) {
|
||||||
MG_ERROR(("invalid listening URL: %s", url));
|
MG_ERROR(("invalid listening URL: %s", url));
|
||||||
@@ -197,47 +197,47 @@ bool mg_open_listener(struct mg_connection *c, const char *url) {
|
|||||||
int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
|
int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
|
||||||
(void) on;
|
(void) on;
|
||||||
|
|
||||||
if ((fd = socket(af, type, proto)) != INVALID_SOCKET &&
|
if ((fd = socket(af, type, proto)) == INVALID_SOCKET) {
|
||||||
|
MG_ERROR(("socket: %s", MG_SOCK_ERRNO));
|
||||||
#if (MG_ARCH != MG_ARCH_WIN32 || !defined(SO_EXCLUSIVEADDRUSE)) && \
|
#if (MG_ARCH != MG_ARCH_WIN32 || !defined(SO_EXCLUSIVEADDRUSE)) && \
|
||||||
(!defined(LWIP_SOCKET) || (defined(LWIP_SOCKET) && SO_REUSE == 1))
|
(!defined(LWIP_SOCKET) || (defined(LWIP_SOCKET) && SO_REUSE == 1))
|
||||||
// 1. SO_RESUSEADDR is not enabled on Windows because the semantics of
|
} else if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on,
|
||||||
// SO_REUSEADDR on UNIX and Windows is different. On Windows,
|
sizeof(on)) != 0) {
|
||||||
// SO_REUSEADDR allows to bind a socket to a port without error even
|
// 1. SO_RESUSEADDR is not enabled on Windows because the semantics of
|
||||||
// if the port is already open by another program. This is not the
|
// SO_REUSEADDR on UNIX and Windows is different. On Windows,
|
||||||
// behavior SO_REUSEADDR was designed for, and leads to hard-to-track
|
// SO_REUSEADDR allows to bind a socket to a port without error even
|
||||||
// failure scenarios. Therefore, SO_REUSEADDR was disabled on Windows
|
// if the port is already open by another program. This is not the
|
||||||
// unless SO_EXCLUSIVEADDRUSE is supported and set on a socket.
|
// behavior SO_REUSEADDR was designed for, and leads to hard-to-track
|
||||||
// 2. In case of LWIP, SO_REUSEADDR should be explicitly enabled, by
|
// failure scenarios. Therefore, SO_REUSEADDR was disabled on Windows
|
||||||
// defining
|
// unless SO_EXCLUSIVEADDRUSE is supported and set on a socket.
|
||||||
// SO_REUSE (in lwipopts.h), otherwise the code below will compile
|
// 2. In case of LWIP, SO_REUSEADDR should be explicitly enabled, by
|
||||||
// but won't work! (setsockopt will return EINVAL)
|
// defining
|
||||||
!setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) &&
|
// SO_REUSE (in lwipopts.h), otherwise the code below will compile
|
||||||
|
// but won't work! (setsockopt will return EINVAL)
|
||||||
|
MG_ERROR(("reuseaddr: %s", MG_SOCK_ERRNO));
|
||||||
#endif
|
#endif
|
||||||
#if MG_ARCH == MG_ARCH_WIN32 && defined(SO_EXCLUSIVEADDRUSE) && !defined(WINCE)
|
#if MG_ARCH == MG_ARCH_WIN32 && defined(SO_EXCLUSIVEADDRUSE) && !defined(WINCE)
|
||||||
// "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE"
|
} else if (setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *) &on,
|
||||||
//! setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char *) &on, sizeof(on))
|
sizeof(on)) != 0) {
|
||||||
//! &&
|
// "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE"
|
||||||
!setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *) &on,
|
MG_ERROR(("exclusiveaddruse: %s", MG_SOCK_ERRNO));
|
||||||
sizeof(on)) &&
|
|
||||||
#endif
|
#endif
|
||||||
bind(fd, &usa.sa, slen) == 0 &&
|
} else if (bind(fd, &usa.sa, slen) != 0) {
|
||||||
// NOTE(lsm): FreeRTOS uses backlog value as a connection limit
|
MG_ERROR(("bind: %s", MG_SOCK_ERRNO));
|
||||||
(type == SOCK_DGRAM || listen(fd, MG_SOCK_LISTEN_BACKLOG_SIZE) == 0)) {
|
} else if ((type == SOCK_STREAM &&
|
||||||
|
listen(fd, MG_SOCK_LISTEN_BACKLOG_SIZE) != 0)) {
|
||||||
|
// NOTE(lsm): FreeRTOS uses backlog value as a connection limit
|
||||||
// In case port was set to 0, get the real port number
|
// In case port was set to 0, get the real port number
|
||||||
|
MG_ERROR(("listen: %s", MG_SOCK_ERRNO));
|
||||||
|
} else {
|
||||||
setlocaddr(fd, &c->loc);
|
setlocaddr(fd, &c->loc);
|
||||||
mg_set_non_blocking_mode(fd);
|
mg_set_non_blocking_mode(fd);
|
||||||
} else if (fd != INVALID_SOCKET) {
|
c->fd = S2PTR(fd);
|
||||||
s_err = MG_SOCK_ERRNO;
|
success = true;
|
||||||
closesocket(fd);
|
|
||||||
fd = INVALID_SOCKET;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c->fd = S2PTR(fd);
|
if (success == false && fd != INVALID_SOCKET) closesocket(fd);
|
||||||
if (fd == INVALID_SOCKET) {
|
return success;
|
||||||
if (s_err == 0) s_err = MG_SOCK_ERRNO;
|
|
||||||
MG_ERROR(("failed %s, errno %d (%s)", url, s_err, strerror(s_err)));
|
|
||||||
}
|
|
||||||
return fd != INVALID_SOCKET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static long mg_sock_recv(struct mg_connection *c, void *buf, size_t len) {
|
static long mg_sock_recv(struct mg_connection *c, void *buf, size_t len) {
|
||||||
@@ -375,8 +375,8 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
|
|||||||
if (fd == INVALID_SOCKET) {
|
if (fd == INVALID_SOCKET) {
|
||||||
#if MG_ARCH == MG_ARCH_AZURERTOS
|
#if MG_ARCH == MG_ARCH_AZURERTOS
|
||||||
// AzureRTOS, in non-block socket mode can mark listening socket readable
|
// AzureRTOS, in non-block socket mode can mark listening socket readable
|
||||||
// even it is not. See comment for 'select' func implementation in nx_bsd.c
|
// even it is not. See comment for 'select' func implementation in
|
||||||
// That's not an error, just should try later
|
// nx_bsd.c That's not an error, just should try later
|
||||||
if (MG_SOCK_ERRNO != EAGAIN)
|
if (MG_SOCK_ERRNO != EAGAIN)
|
||||||
#endif
|
#endif
|
||||||
MG_ERROR(("%lu accept failed, errno %d", lsn->id, MG_SOCK_ERRNO));
|
MG_ERROR(("%lu accept failed, errno %d", lsn->id, MG_SOCK_ERRNO));
|
||||||
|
|||||||
Reference in new issue
Block a user