Better error handling for RL NET

This commit is contained in:
cpq 2023-02-01 12:25:30 +00:00
parent d1c9d7ffdc
commit 1612e1d142
5 changed files with 158 additions and 150 deletions

View File

@ -4003,6 +4003,24 @@ struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr, const char *url,
#define AF_INET6 10
#endif
#ifndef MG_SOCK_ERR
#define MG_SOCK_ERR(errcode) ((errcode) < 0 ? errno : 0)
#endif
#ifndef MG_SOCK_INTR
#define MG_SOCK_INTR(fd) (fd == MG_INVALID_SOCKET && MG_SOCK_ERR(-1) == EINTR)
#endif
#ifndef MG_SOCK_PENDING
#define MG_SOCK_PENDING(errcode) \
(((errcode) < 0) && (errno == EINPROGRESS || errno == EWOULDBLOCK))
#endif
#ifndef MG_SOCK_RESET
#define MG_SOCK_RESET(errcode) \
(((errcode) < 0) && (errno == EPIPE || errno == ECONNRESET))
#endif
union usa {
struct sockaddr sa;
struct sockaddr_in sin;
@ -4040,27 +4058,6 @@ static void tomgaddr(union usa *usa, struct mg_addr *a, bool is_ip6) {
#endif
}
static bool mg_sock_would_block(void) {
int err = MG_SOCKET_ERRNO;
return err == EINPROGRESS || err == EWOULDBLOCK
#ifndef WINCE
|| err == EAGAIN || err == EINTR
#endif
#if MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK
|| err == WSAEINTR || err == WSAEWOULDBLOCK
#endif
;
}
static bool mg_sock_conn_reset(void) {
int err = MG_SOCKET_ERRNO;
#if MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK
return err == WSAECONNRESET;
#else
return err == EPIPE || err == ECONNRESET;
#endif
}
static void setlocaddr(MG_SOCKET_TYPE fd, struct mg_addr *addr) {
union usa usa;
socklen_t n = sizeof(usa);
@ -4107,12 +4104,9 @@ long mg_io_send(struct mg_connection *c, const void *buf, size_t len) {
if (n > 0) setlocaddr(FD(c), &c->loc);
} else {
n = send(FD(c), (char *) buf, len, MSG_NONBLOCKING);
#if MG_ARCH == MG_ARCH_RTX
if (n == EWOULDBLOCK) return MG_IO_WAIT;
#endif
}
if (n < 0 && mg_sock_would_block()) return MG_IO_WAIT;
if (n < 0 && mg_sock_conn_reset()) return MG_IO_RESET;
if (MG_SOCK_PENDING(n)) return MG_IO_WAIT;
if (MG_SOCK_RESET(n)) return MG_IO_RESET;
if (n <= 0) return MG_IO_ERR;
return n;
}
@ -4121,7 +4115,7 @@ bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
if (c->is_udp) {
long n = mg_io_send(c, buf, len);
MG_DEBUG(("%lu %p %d:%d %ld err %d", c->id, c->fd, (int) c->send.len,
(int) c->recv.len, n, MG_SOCKET_ERRNO));
(int) c->recv.len, n, MG_SOCK_ERR(n)));
iolog(c, (char *) buf, n, false);
return n > 0;
} else {
@ -4169,17 +4163,17 @@ bool mg_open_listener(struct mg_connection *c, const char *url) {
} else {
union usa usa;
socklen_t slen = tousa(&c->loc, &usa);
int on = 1, af = c->loc.is_ip6 ? AF_INET6 : AF_INET;
int rc, 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;
if ((fd = socket(af, type, proto)) == MG_INVALID_SOCKET) {
MG_ERROR(("socket: %d", MG_SOCKET_ERRNO));
MG_ERROR(("socket: %d", MG_SOCK_ERR(-1)));
#if ((MG_ARCH == MG_ARCH_WIN32) || (MG_ARCH == MG_ARCH_UNIX) || \
(defined(LWIP_SOCKET) && SO_REUSE == 1))
} else if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on,
sizeof(on)) != 0) {
} else if ((rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on,
sizeof(on))) != 0) {
// 1. SO_RESUSEADDR is not enabled on Windows because the semantics of
// SO_REUSEADDR on UNIX and Windows is different. On Windows,
// SO_REUSEADDR allows to bind a socket to a port without error even
@ -4191,21 +4185,21 @@ bool mg_open_listener(struct mg_connection *c, const char *url) {
// defining
// SO_REUSE (in lwipopts.h), otherwise the code below will compile
// but won't work! (setsockopt will return EINVAL)
MG_ERROR(("reuseaddr: %d", MG_SOCKET_ERRNO));
MG_ERROR(("reuseaddr: %d", MG_SOCK_ERR(rc)));
#endif
#if MG_ARCH == MG_ARCH_WIN32 && !defined(SO_EXCLUSIVEADDRUSE) && !defined(WINCE)
} else if (setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *) &on,
sizeof(on)) != 0) {
} else if ((rc = setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
(char *) &on, sizeof(on))) != 0) {
// "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE"
MG_ERROR(("exclusiveaddruse: %d", MG_SOCKET_ERRNO));
MG_ERROR(("exclusiveaddruse: %d", MG_SOCK_ERR(rc)));
#endif
} else if (bind(fd, &usa.sa, slen) != 0) {
MG_ERROR(("bind: %d", MG_SOCKET_ERRNO));
} else if ((rc = bind(fd, &usa.sa, slen)) != 0) {
MG_ERROR(("bind: %d", MG_SOCK_ERR(rc)));
} else if ((type == SOCK_STREAM &&
listen(fd, MG_SOCK_LISTEN_BACKLOG_SIZE) != 0)) {
(rc = 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
MG_ERROR(("listen: %d", MG_SOCKET_ERRNO));
MG_ERROR(("listen: %d", MG_SOCK_ERR(rc)));
} else {
setlocaddr(fd, &c->loc);
mg_set_non_blocking_mode(fd);
@ -4228,8 +4222,8 @@ long mg_io_recv(struct mg_connection *c, void *buf, size_t len) {
} else {
n = recv(FD(c), (char *) buf, len, MSG_NONBLOCKING);
}
if (n < 0 && mg_sock_would_block()) return MG_IO_WAIT;
if (n < 0 && mg_sock_conn_reset()) return MG_IO_RESET;
if (MG_SOCK_PENDING(n)) return MG_IO_WAIT;
if (MG_SOCK_RESET(n)) return MG_IO_RESET;
if (n <= 0) return MG_IO_ERR;
return n;
}
@ -4249,7 +4243,7 @@ static void read_conn(struct mg_connection *c) {
n = c->is_tls ? mg_tls_recv(c, buf, len) : mg_io_recv(c, buf, len);
MG_DEBUG(("%lu %p snd %ld/%ld rcv %ld/%ld n=%ld err=%d", c->id, c->fd,
(long) c->send.len, (long) c->send.size, (long) c->recv.len,
(long) c->recv.size, n, MG_SOCKET_ERRNO));
(long) c->recv.size, n, MG_SOCK_ERR(n)));
iolog(c, buf, n, true);
}
}
@ -4260,7 +4254,7 @@ static void write_conn(struct mg_connection *c) {
long n = c->is_tls ? mg_tls_send(c, buf, len) : mg_io_send(c, buf, len);
MG_DEBUG(("%lu %p snd %ld/%ld rcv %ld/%ld n=%ld err=%d", c->id, c->fd,
(long) c->send.len, (long) c->send.size, (long) c->recv.len,
(long) c->recv.size, n, MG_SOCKET_ERRNO));
(long) c->recv.size, n, MG_SOCK_ERR(n)));
iolog(c, buf, n, false);
}
@ -4314,14 +4308,14 @@ void mg_connect_resolved(struct mg_connection *c) {
c->fd = S2PTR(socket(af, type, 0)); // Create outbound socket
c->is_resolving = 0; // Clear resolving flag
if (FD(c) == MG_INVALID_SOCKET) {
mg_error(c, "socket(): %d", MG_SOCKET_ERRNO);
mg_error(c, "socket(): %d", MG_SOCK_ERR(-1));
} else if (c->is_udp) {
MG_EPOLL_ADD(c);
#if MG_ARCH == MG_ARCH_TIRTOS
union usa usa; // TI-RTOS NDK requires binding to receive on UDP sockets
socklen_t slen = tousa(&c->loc, &usa);
if (bind(c->fd, &usa.sa, slen) != 0)
MG_ERROR(("bind: %d", MG_SOCKET_ERRNO));
if ((rc = bind(c->fd, &usa.sa, slen)) != 0)
MG_ERROR(("bind: %d", MG_SOCK_ERR(rc)));
#endif
mg_call(c, MG_EV_RESOLVE, NULL);
mg_call(c, MG_EV_CONNECT, NULL);
@ -4332,26 +4326,26 @@ void mg_connect_resolved(struct mg_connection *c) {
setsockopts(c);
MG_EPOLL_ADD(c);
mg_call(c, MG_EV_RESOLVE, NULL);
if ((rc = connect(FD(c), &usa.sa, slen)) == 0) {
mg_call(c, MG_EV_CONNECT, NULL);
} else if (mg_sock_would_block()) {
rc = connect(FD(c), &usa.sa, slen); // Attempt to connect
if (rc == 0) { // Success
mg_call(c, MG_EV_CONNECT, NULL); // Send MG_EV_CONNECT to the user
} else if (MG_SOCK_PENDING(rc)) { // Need to wait for TCP handshake
MG_DEBUG(("%lu %p -> %M pend", c->id, c->fd, mg_print_ip_port, &c->rem));
c->is_connecting = 1;
} else {
mg_error(c, "connect: %d", MG_SOCKET_ERRNO);
mg_error(c, "connect: %d", MG_SOCK_ERR(rc));
}
}
(void) rc;
}
static MG_SOCKET_TYPE raccept(MG_SOCKET_TYPE sock, union usa *usa,
socklen_t *len) {
MG_SOCKET_TYPE s = MG_INVALID_SOCKET;
MG_SOCKET_TYPE fd = MG_INVALID_SOCKET;
do {
memset(usa, 0, sizeof(*usa));
s = accept(sock, &usa->sa, len);
} while (s == MG_INVALID_SOCKET && errno == EINTR);
return s;
fd = accept(sock, &usa->sa, len);
} while (MG_SOCK_INTR(fd));
return fd;
}
static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
@ -4364,9 +4358,9 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
// 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 That's not an error, just should try later
if (MG_SOCKET_ERRNO != EAGAIN)
if (errno != EAGAIN)
#endif
MG_ERROR(("%lu accept failed, errno %d", lsn->id, MG_SOCKET_ERRNO));
MG_ERROR(("%lu accept failed, errno %d", lsn->id, MG_SOCK_ERR(-1)));
#if (MG_ARCH != MG_ARCH_WIN32) && !MG_ENABLE_FREERTOS_TCP && \
(MG_ARCH != MG_ARCH_TIRTOS) && !MG_ENABLE_POLL
} else if ((long) fd >= FD_SETSIZE) {
@ -4576,7 +4570,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
#if MG_ARCH == MG_ARCH_WIN32
if (maxfd == 0) Sleep(ms); // On Windows, select fails if no sockets
#else
MG_ERROR(("select: %d %d", rc, MG_SOCKET_ERRNO));
MG_ERROR(("select: %d %d", rc, MG_SOCK_ERR(rc)));
#endif
FD_ZERO(&rset);
FD_ZERO(&wset);
@ -5352,6 +5346,7 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) {
if (opts->srvname.len > 0) {
char *s = mg_mprintf("%.*s", (int) opts->srvname.len, opts->srvname.ptr);
SSL_set1_host(tls->ssl, s);
SSL_set_tlsext_host_name(tls->ssl, s);
free(s);
}
#endif
@ -6110,7 +6105,6 @@ static size_t mip_driver_stm32_tx(const void *buf, size_t len, struct mip_if *if
s_txdesc[s_txno][0] = BIT(20) | BIT(28) | BIT(29) | BIT(30); // Chain,FS,LS
s_txdesc[s_txno][0] |= BIT(31); // Set OWN bit - let DMA take over
if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
printf("sent\n");
}
ETH->DMASR = BIT(2) | BIT(5); // Clear any prior TBUS/TUS
ETH->DMATPDR = 0; // and resume
@ -6124,11 +6118,9 @@ static bool mip_driver_stm32_up(struct mip_if *ifp) {
return bsr & BIT(2) ? 1 : 0;
}
static uint32_t s_rxno;
void ETH_IRQHandler(void);
static uint32_t s_rxno;
void ETH_IRQHandler(void) {
static int cnt;
printf("--> %d\n", cnt++);
qp_mark(QP_IRQTRIGGERED, 0);
if (ETH->DMASR & BIT(6)) { // Frame received, loop
ETH->DMASR = BIT(16) | BIT(6); // Clear flag

View File

@ -403,7 +403,6 @@ typedef enum { false = 0, true = 1 } bool;
#define MG_INVALID_SOCKET INVALID_SOCKET
#define MG_SOCKET_TYPE SOCKET
typedef unsigned long nfds_t;
#define MG_SOCKET_ERRNO WSAGetLastError()
#if defined(_MSC_VER)
#pragma comment(lib, "ws2_32.lib")
#ifndef alloca
@ -411,9 +410,6 @@ typedef unsigned long nfds_t;
#endif
#endif
#define poll(a, b, c) WSAPoll((a), (b), (c))
#ifndef SO_EXCLUSIVEADDRUSE
#define SO_EXCLUSIVEADDRUSE ((int) (~SO_REUSEADDR))
#endif
#define closesocket(x) closesocket(x)
typedef int socklen_t;
@ -423,13 +419,20 @@ typedef int socklen_t;
#define MG_PATH_MAX FILENAME_MAX
#endif
#ifndef EINPROGRESS
#define EINPROGRESS WSAEINPROGRESS
#endif
#ifndef EWOULDBLOCK
#define EWOULDBLOCK WSAEWOULDBLOCK
#ifndef SO_EXCLUSIVEADDRUSE
#define SO_EXCLUSIVEADDRUSE ((int) (~SO_REUSEADDR))
#endif
#define MG_SOCK_ERR(errcode) ((errcode) < 0 ? WSAGetLastError() : 0)
#define MG_SOCK_PENDING(errcode) \
(((errcode) < 0) && \
(WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEINPROGRESS || \
WSAGetLastError() == WSAEWOULDBLOCK))
#define MG_SOCK_RESET(errcode) \
(((errcode) < 0) && (WSAGetLastError() == WSAECONNRESET))
#define realpath(a, b) _fullpath((b), (a), MG_PATH_MAX)
#define sleep(x) Sleep(x)
#define mkdir(a, b) _mkdir(a)
@ -568,13 +571,21 @@ struct timeval {
#define MG_ENABLE_CUSTOM_MILLIS 1
#define closesocket(x) closesocket(x)
#define mkdir(a, b) (-1)
#define EWOULDBLOCK BSD_EWOULDBLOCK
#define EAGAIN BSD_EWOULDBLOCK
#define EINPROGRESS BSD_EWOULDBLOCK
#define EINTR BSD_EWOULDBLOCK
#define ECONNRESET BSD_ECONNRESET
#define EPIPE BSD_ECONNRESET
#define TCP_NODELAY SO_KEEPALIVE
#define MG_SOCK_ERR(errcode) ((errcode) < 0 ? (errcode) : 0)
#define MG_SOCK_PENDING(errcode) \
((errcode) == BSD_EWOULDBLOCK || (errcode) == BSD_EALREADY || \
(errcode) == BSD_EINPROGRESS)
#define MG_SOCK_RESET(errcode) \
((errcode) == BSD_ECONNABORTED || (errcode) == BSD_ECONNRESET)
#define MG_SOCK_INTR(fd) 0
#define socklen_t int
#endif

View File

@ -63,7 +63,6 @@ typedef enum { false = 0, true = 1 } bool;
#define MG_INVALID_SOCKET INVALID_SOCKET
#define MG_SOCKET_TYPE SOCKET
typedef unsigned long nfds_t;
#define MG_SOCKET_ERRNO WSAGetLastError()
#if defined(_MSC_VER)
#pragma comment(lib, "ws2_32.lib")
#ifndef alloca
@ -71,9 +70,6 @@ typedef unsigned long nfds_t;
#endif
#endif
#define poll(a, b, c) WSAPoll((a), (b), (c))
#ifndef SO_EXCLUSIVEADDRUSE
#define SO_EXCLUSIVEADDRUSE ((int) (~SO_REUSEADDR))
#endif
#define closesocket(x) closesocket(x)
typedef int socklen_t;
@ -83,13 +79,20 @@ typedef int socklen_t;
#define MG_PATH_MAX FILENAME_MAX
#endif
#ifndef EINPROGRESS
#define EINPROGRESS WSAEINPROGRESS
#endif
#ifndef EWOULDBLOCK
#define EWOULDBLOCK WSAEWOULDBLOCK
#ifndef SO_EXCLUSIVEADDRUSE
#define SO_EXCLUSIVEADDRUSE ((int) (~SO_REUSEADDR))
#endif
#define MG_SOCK_ERR(errcode) ((errcode) < 0 ? WSAGetLastError() : 0)
#define MG_SOCK_PENDING(errcode) \
(((errcode) < 0) && \
(WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEINPROGRESS || \
WSAGetLastError() == WSAEWOULDBLOCK))
#define MG_SOCK_RESET(errcode) \
(((errcode) < 0) && (WSAGetLastError() == WSAECONNRESET))
#define realpath(a, b) _fullpath((b), (a), MG_PATH_MAX)
#define sleep(x) Sleep(x)
#define mkdir(a, b) _mkdir(a)

View File

@ -6,11 +6,19 @@
#define MG_ENABLE_CUSTOM_MILLIS 1
#define closesocket(x) closesocket(x)
#define mkdir(a, b) (-1)
#define EWOULDBLOCK BSD_EWOULDBLOCK
#define EAGAIN BSD_EWOULDBLOCK
#define EINPROGRESS BSD_EWOULDBLOCK
#define EINTR BSD_EWOULDBLOCK
#define ECONNRESET BSD_ECONNRESET
#define EPIPE BSD_ECONNRESET
#define TCP_NODELAY SO_KEEPALIVE
#define MG_SOCK_ERR(errcode) ((errcode) < 0 ? (errcode) : 0)
#define MG_SOCK_PENDING(errcode) \
((errcode) == BSD_EWOULDBLOCK || (errcode) == BSD_EALREADY || \
(errcode) == BSD_EINPROGRESS)
#define MG_SOCK_RESET(errcode) \
((errcode) == BSD_ECONNABORTED || (errcode) == BSD_ECONNRESET)
#define MG_SOCK_INTR(fd) 0
#define socklen_t int
#endif

View File

@ -25,6 +25,24 @@
#define AF_INET6 10
#endif
#ifndef MG_SOCK_ERR
#define MG_SOCK_ERR(errcode) ((errcode) < 0 ? errno : 0)
#endif
#ifndef MG_SOCK_INTR
#define MG_SOCK_INTR(fd) (fd == MG_INVALID_SOCKET && MG_SOCK_ERR(-1) == EINTR)
#endif
#ifndef MG_SOCK_PENDING
#define MG_SOCK_PENDING(errcode) \
(((errcode) < 0) && (errno == EINPROGRESS || errno == EWOULDBLOCK))
#endif
#ifndef MG_SOCK_RESET
#define MG_SOCK_RESET(errcode) \
(((errcode) < 0) && (errno == EPIPE || errno == ECONNRESET))
#endif
union usa {
struct sockaddr sa;
struct sockaddr_in sin;
@ -62,27 +80,6 @@ static void tomgaddr(union usa *usa, struct mg_addr *a, bool is_ip6) {
#endif
}
static bool mg_sock_would_block(void) {
int err = MG_SOCKET_ERRNO;
return err == EINPROGRESS || err == EWOULDBLOCK
#ifndef WINCE
|| err == EAGAIN || err == EINTR
#endif
#if MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK
|| err == WSAEINTR || err == WSAEWOULDBLOCK
#endif
;
}
static bool mg_sock_conn_reset(void) {
int err = MG_SOCKET_ERRNO;
#if MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK
return err == WSAECONNRESET;
#else
return err == EPIPE || err == ECONNRESET;
#endif
}
static void setlocaddr(MG_SOCKET_TYPE fd, struct mg_addr *addr) {
union usa usa;
socklen_t n = sizeof(usa);
@ -129,12 +126,9 @@ long mg_io_send(struct mg_connection *c, const void *buf, size_t len) {
if (n > 0) setlocaddr(FD(c), &c->loc);
} else {
n = send(FD(c), (char *) buf, len, MSG_NONBLOCKING);
#if MG_ARCH == MG_ARCH_RTX
if (n == EWOULDBLOCK) return MG_IO_WAIT;
#endif
}
if (n < 0 && mg_sock_would_block()) return MG_IO_WAIT;
if (n < 0 && mg_sock_conn_reset()) return MG_IO_RESET;
if (MG_SOCK_PENDING(n)) return MG_IO_WAIT;
if (MG_SOCK_RESET(n)) return MG_IO_RESET;
if (n <= 0) return MG_IO_ERR;
return n;
}
@ -143,7 +137,7 @@ bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
if (c->is_udp) {
long n = mg_io_send(c, buf, len);
MG_DEBUG(("%lu %p %d:%d %ld err %d", c->id, c->fd, (int) c->send.len,
(int) c->recv.len, n, MG_SOCKET_ERRNO));
(int) c->recv.len, n, MG_SOCK_ERR(n)));
iolog(c, (char *) buf, n, false);
return n > 0;
} else {
@ -191,17 +185,17 @@ bool mg_open_listener(struct mg_connection *c, const char *url) {
} else {
union usa usa;
socklen_t slen = tousa(&c->loc, &usa);
int on = 1, af = c->loc.is_ip6 ? AF_INET6 : AF_INET;
int rc, 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;
if ((fd = socket(af, type, proto)) == MG_INVALID_SOCKET) {
MG_ERROR(("socket: %d", MG_SOCKET_ERRNO));
MG_ERROR(("socket: %d", MG_SOCK_ERR(-1)));
#if ((MG_ARCH == MG_ARCH_WIN32) || (MG_ARCH == MG_ARCH_UNIX) || \
(defined(LWIP_SOCKET) && SO_REUSE == 1))
} else if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on,
sizeof(on)) != 0) {
} else if ((rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on,
sizeof(on))) != 0) {
// 1. SO_RESUSEADDR is not enabled on Windows because the semantics of
// SO_REUSEADDR on UNIX and Windows is different. On Windows,
// SO_REUSEADDR allows to bind a socket to a port without error even
@ -213,21 +207,21 @@ bool mg_open_listener(struct mg_connection *c, const char *url) {
// defining
// SO_REUSE (in lwipopts.h), otherwise the code below will compile
// but won't work! (setsockopt will return EINVAL)
MG_ERROR(("reuseaddr: %d", MG_SOCKET_ERRNO));
MG_ERROR(("reuseaddr: %d", MG_SOCK_ERR(rc)));
#endif
#if MG_ARCH == MG_ARCH_WIN32 && !defined(SO_EXCLUSIVEADDRUSE) && !defined(WINCE)
} else if (setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *) &on,
sizeof(on)) != 0) {
} else if ((rc = setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
(char *) &on, sizeof(on))) != 0) {
// "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE"
MG_ERROR(("exclusiveaddruse: %d", MG_SOCKET_ERRNO));
MG_ERROR(("exclusiveaddruse: %d", MG_SOCK_ERR(rc)));
#endif
} else if (bind(fd, &usa.sa, slen) != 0) {
MG_ERROR(("bind: %d", MG_SOCKET_ERRNO));
} else if ((rc = bind(fd, &usa.sa, slen)) != 0) {
MG_ERROR(("bind: %d", MG_SOCK_ERR(rc)));
} else if ((type == SOCK_STREAM &&
listen(fd, MG_SOCK_LISTEN_BACKLOG_SIZE) != 0)) {
(rc = 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
MG_ERROR(("listen: %d", MG_SOCKET_ERRNO));
MG_ERROR(("listen: %d", MG_SOCK_ERR(rc)));
} else {
setlocaddr(fd, &c->loc);
mg_set_non_blocking_mode(fd);
@ -250,8 +244,8 @@ long mg_io_recv(struct mg_connection *c, void *buf, size_t len) {
} else {
n = recv(FD(c), (char *) buf, len, MSG_NONBLOCKING);
}
if (n < 0 && mg_sock_would_block()) return MG_IO_WAIT;
if (n < 0 && mg_sock_conn_reset()) return MG_IO_RESET;
if (MG_SOCK_PENDING(n)) return MG_IO_WAIT;
if (MG_SOCK_RESET(n)) return MG_IO_RESET;
if (n <= 0) return MG_IO_ERR;
return n;
}
@ -271,7 +265,7 @@ static void read_conn(struct mg_connection *c) {
n = c->is_tls ? mg_tls_recv(c, buf, len) : mg_io_recv(c, buf, len);
MG_DEBUG(("%lu %p snd %ld/%ld rcv %ld/%ld n=%ld err=%d", c->id, c->fd,
(long) c->send.len, (long) c->send.size, (long) c->recv.len,
(long) c->recv.size, n, MG_SOCKET_ERRNO));
(long) c->recv.size, n, MG_SOCK_ERR(n)));
iolog(c, buf, n, true);
}
}
@ -282,7 +276,7 @@ static void write_conn(struct mg_connection *c) {
long n = c->is_tls ? mg_tls_send(c, buf, len) : mg_io_send(c, buf, len);
MG_DEBUG(("%lu %p snd %ld/%ld rcv %ld/%ld n=%ld err=%d", c->id, c->fd,
(long) c->send.len, (long) c->send.size, (long) c->recv.len,
(long) c->recv.size, n, MG_SOCKET_ERRNO));
(long) c->recv.size, n, MG_SOCK_ERR(n)));
iolog(c, buf, n, false);
}
@ -336,14 +330,14 @@ void mg_connect_resolved(struct mg_connection *c) {
c->fd = S2PTR(socket(af, type, 0)); // Create outbound socket
c->is_resolving = 0; // Clear resolving flag
if (FD(c) == MG_INVALID_SOCKET) {
mg_error(c, "socket(): %d", MG_SOCKET_ERRNO);
mg_error(c, "socket(): %d", MG_SOCK_ERR(-1));
} else if (c->is_udp) {
MG_EPOLL_ADD(c);
#if MG_ARCH == MG_ARCH_TIRTOS
union usa usa; // TI-RTOS NDK requires binding to receive on UDP sockets
socklen_t slen = tousa(&c->loc, &usa);
if (bind(c->fd, &usa.sa, slen) != 0)
MG_ERROR(("bind: %d", MG_SOCKET_ERRNO));
if ((rc = bind(c->fd, &usa.sa, slen)) != 0)
MG_ERROR(("bind: %d", MG_SOCK_ERR(rc)));
#endif
mg_call(c, MG_EV_RESOLVE, NULL);
mg_call(c, MG_EV_CONNECT, NULL);
@ -354,26 +348,26 @@ void mg_connect_resolved(struct mg_connection *c) {
setsockopts(c);
MG_EPOLL_ADD(c);
mg_call(c, MG_EV_RESOLVE, NULL);
if ((rc = connect(FD(c), &usa.sa, slen)) == 0) {
mg_call(c, MG_EV_CONNECT, NULL);
} else if (mg_sock_would_block()) {
rc = connect(FD(c), &usa.sa, slen); // Attempt to connect
if (rc == 0) { // Success
mg_call(c, MG_EV_CONNECT, NULL); // Send MG_EV_CONNECT to the user
} else if (MG_SOCK_PENDING(rc)) { // Need to wait for TCP handshake
MG_DEBUG(("%lu %p -> %M pend", c->id, c->fd, mg_print_ip_port, &c->rem));
c->is_connecting = 1;
} else {
mg_error(c, "connect: %d", MG_SOCKET_ERRNO);
mg_error(c, "connect: %d", MG_SOCK_ERR(rc));
}
}
(void) rc;
}
static MG_SOCKET_TYPE raccept(MG_SOCKET_TYPE sock, union usa *usa,
socklen_t *len) {
MG_SOCKET_TYPE s = MG_INVALID_SOCKET;
MG_SOCKET_TYPE fd = MG_INVALID_SOCKET;
do {
memset(usa, 0, sizeof(*usa));
s = accept(sock, &usa->sa, len);
} while (s == MG_INVALID_SOCKET && errno == EINTR);
return s;
fd = accept(sock, &usa->sa, len);
} while (MG_SOCK_INTR(fd));
return fd;
}
static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
@ -386,9 +380,9 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
// 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 That's not an error, just should try later
if (MG_SOCKET_ERRNO != EAGAIN)
if (errno != EAGAIN)
#endif
MG_ERROR(("%lu accept failed, errno %d", lsn->id, MG_SOCKET_ERRNO));
MG_ERROR(("%lu accept failed, errno %d", lsn->id, MG_SOCK_ERR(-1)));
#if (MG_ARCH != MG_ARCH_WIN32) && !MG_ENABLE_FREERTOS_TCP && \
(MG_ARCH != MG_ARCH_TIRTOS) && !MG_ENABLE_POLL
} else if ((long) fd >= FD_SETSIZE) {
@ -598,7 +592,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
#if MG_ARCH == MG_ARCH_WIN32
if (maxfd == 0) Sleep(ms); // On Windows, select fails if no sockets
#else
MG_ERROR(("select: %d %d", rc, MG_SOCKET_ERRNO));
MG_ERROR(("select: %d %d", rc, MG_SOCK_ERR(rc)));
#endif
FD_ZERO(&rset);
FD_ZERO(&wset);