mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-16 10:39:49 +00:00
Fix #2603: TLS read path
This commit is contained in:
1 parent
c8d45c9ff1
commit
9172f62970
2 files changed
+26
-18
No files matched your search
+13
-9
@@ -7188,6 +7188,7 @@ long mg_io_send(struct mg_connection *c, const void *buf, size_t len) {
|
||||
} else {
|
||||
n = send(FD(c), (char *) buf, len, MSG_NONBLOCKING);
|
||||
}
|
||||
MG_VERBOSE(("%lu %ld %d", c->id, n, MG_SOCK_ERR(n)));
|
||||
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;
|
||||
@@ -7309,6 +7310,7 @@ static long recv_raw(struct mg_connection *c, void *buf, size_t len) {
|
||||
} else {
|
||||
n = recv(FD(c), (char *) buf, len, MSG_NONBLOCKING);
|
||||
}
|
||||
MG_VERBOSE(("%lu %ld %d", c->id, n, MG_SOCK_ERR(n)));
|
||||
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;
|
||||
@@ -7339,8 +7341,7 @@ static void read_conn(struct mg_connection *c) {
|
||||
if (!ioalloc(c, &c->rtls)) return;
|
||||
n = recv_raw(c, (char *) &c->rtls.buf[c->rtls.len],
|
||||
c->rtls.size - c->rtls.len);
|
||||
// MG_DEBUG(("%lu %ld", c->id, n));
|
||||
if (n == MG_IO_ERR && mg_tls_pending(c) == 0 && c->rtls.len == 0) {
|
||||
if (n == MG_IO_ERR && c->rtls.len == 0) {
|
||||
// Close only if we have fully drained both raw (rtls) and TLS buffers
|
||||
c->is_closing = 1;
|
||||
} else {
|
||||
@@ -7539,7 +7540,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
|
||||
size_t max = 1;
|
||||
for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) {
|
||||
c->is_readable = c->is_writable = 0;
|
||||
if (mg_tls_pending(c) > 0) ms = 1, c->is_readable = 1;
|
||||
if (c->rtls.len > 0) ms = 1, c->is_readable = 1;
|
||||
if (can_write(c)) MG_EPOLL_MOD(c, 1);
|
||||
if (c->is_closing) ms = 1;
|
||||
max++;
|
||||
@@ -7555,6 +7556,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
|
||||
bool wr = evs[i].events & EPOLLOUT;
|
||||
c->is_readable = can_read(c) && rd ? 1U : 0;
|
||||
c->is_writable = can_write(c) && wr ? 1U : 0;
|
||||
if (c->rtls.len > 0) c->is_readable = 1;
|
||||
}
|
||||
}
|
||||
(void) skip_iotest;
|
||||
@@ -7568,7 +7570,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
|
||||
c->is_readable = c->is_writable = 0;
|
||||
if (skip_iotest(c)) {
|
||||
// Socket not valid, ignore
|
||||
} else if (mg_tls_pending(c) > 0) {
|
||||
} else if (c->rtls.len > 0) {
|
||||
ms = 1; // Don't wait if TLS is ready
|
||||
} else {
|
||||
fds[n].fd = FD(c);
|
||||
@@ -7590,7 +7592,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
|
||||
for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) {
|
||||
if (skip_iotest(c)) {
|
||||
// Socket not valid, ignore
|
||||
} else if (mg_tls_pending(c) > 0) {
|
||||
} else if (c->rtls.len > 0) {
|
||||
c->is_readable = 1;
|
||||
} else {
|
||||
if (fds[n].revents & POLLERR) {
|
||||
@@ -7599,6 +7601,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
|
||||
c->is_readable =
|
||||
(unsigned) (fds[n].revents & (POLLIN | POLLHUP) ? 1 : 0);
|
||||
c->is_writable = (unsigned) (fds[n].revents & POLLOUT ? 1 : 0);
|
||||
if (c->rtls.len > 0) c->is_readable = 1;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
@@ -7620,7 +7623,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
|
||||
FD_SET(FD(c), &eset);
|
||||
if (can_read(c)) FD_SET(FD(c), &rset);
|
||||
if (can_write(c)) FD_SET(FD(c), &wset);
|
||||
if (mg_tls_pending(c) > 0) tvp = &tv_zero;
|
||||
if (c->rtls.len > 0) tvp = &tv_zero;
|
||||
if (FD(c) > maxfd) maxfd = FD(c);
|
||||
if (c->is_closing) ms = 1;
|
||||
}
|
||||
@@ -7642,7 +7645,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
|
||||
} else {
|
||||
c->is_readable = FD(c) != MG_INVALID_SOCKET && FD_ISSET(FD(c), &rset);
|
||||
c->is_writable = FD(c) != MG_INVALID_SOCKET && FD_ISSET(FD(c), &wset);
|
||||
if (mg_tls_pending(c) > 0) c->is_readable = 1;
|
||||
if (c->rtls.len > 0) c->is_readable = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -7750,10 +7753,11 @@ void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
|
||||
long n = 0;
|
||||
mg_call(c, MG_EV_READ, &n);
|
||||
}
|
||||
MG_VERBOSE(("%lu %c%c %c%c%c%c%c", c->id, c->is_readable ? 'r' : '-',
|
||||
MG_VERBOSE(("%lu %c%c %c%c%c%c%c %lu %lu", c->id, c->is_readable ? 'r' : '-',
|
||||
c->is_writable ? 'w' : '-', c->is_tls ? 'T' : 't',
|
||||
c->is_connecting ? 'C' : 'c', c->is_tls_hs ? 'H' : 'h',
|
||||
c->is_resolving ? 'R' : 'r', c->is_closing ? 'C' : 'c'));
|
||||
c->is_resolving ? 'R' : 'r', c->is_closing ? 'C' : 'c',
|
||||
mg_tls_pending(c), c->rtls.len));
|
||||
if (c->is_resolving || c->is_closing) {
|
||||
// Do nothing
|
||||
} else if (c->is_listening && c->is_udp == 0) {
|
||||
|
||||
+13
-9
@@ -130,6 +130,7 @@ long mg_io_send(struct mg_connection *c, const void *buf, size_t len) {
|
||||
} else {
|
||||
n = send(FD(c), (char *) buf, len, MSG_NONBLOCKING);
|
||||
}
|
||||
MG_VERBOSE(("%lu %ld %d", c->id, n, MG_SOCK_ERR(n)));
|
||||
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;
|
||||
@@ -251,6 +252,7 @@ static long recv_raw(struct mg_connection *c, void *buf, size_t len) {
|
||||
} else {
|
||||
n = recv(FD(c), (char *) buf, len, MSG_NONBLOCKING);
|
||||
}
|
||||
MG_VERBOSE(("%lu %ld %d", c->id, n, MG_SOCK_ERR(n)));
|
||||
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;
|
||||
@@ -281,8 +283,7 @@ static void read_conn(struct mg_connection *c) {
|
||||
if (!ioalloc(c, &c->rtls)) return;
|
||||
n = recv_raw(c, (char *) &c->rtls.buf[c->rtls.len],
|
||||
c->rtls.size - c->rtls.len);
|
||||
// MG_DEBUG(("%lu %ld", c->id, n));
|
||||
if (n == MG_IO_ERR && mg_tls_pending(c) == 0 && c->rtls.len == 0) {
|
||||
if (n == MG_IO_ERR && c->rtls.len == 0) {
|
||||
// Close only if we have fully drained both raw (rtls) and TLS buffers
|
||||
c->is_closing = 1;
|
||||
} else {
|
||||
@@ -481,7 +482,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
|
||||
size_t max = 1;
|
||||
for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) {
|
||||
c->is_readable = c->is_writable = 0;
|
||||
if (mg_tls_pending(c) > 0) ms = 1, c->is_readable = 1;
|
||||
if (c->rtls.len > 0) ms = 1, c->is_readable = 1;
|
||||
if (can_write(c)) MG_EPOLL_MOD(c, 1);
|
||||
if (c->is_closing) ms = 1;
|
||||
max++;
|
||||
@@ -497,6 +498,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
|
||||
bool wr = evs[i].events & EPOLLOUT;
|
||||
c->is_readable = can_read(c) && rd ? 1U : 0;
|
||||
c->is_writable = can_write(c) && wr ? 1U : 0;
|
||||
if (c->rtls.len > 0) c->is_readable = 1;
|
||||
}
|
||||
}
|
||||
(void) skip_iotest;
|
||||
@@ -510,7 +512,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
|
||||
c->is_readable = c->is_writable = 0;
|
||||
if (skip_iotest(c)) {
|
||||
// Socket not valid, ignore
|
||||
} else if (mg_tls_pending(c) > 0) {
|
||||
} else if (c->rtls.len > 0) {
|
||||
ms = 1; // Don't wait if TLS is ready
|
||||
} else {
|
||||
fds[n].fd = FD(c);
|
||||
@@ -532,7 +534,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
|
||||
for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) {
|
||||
if (skip_iotest(c)) {
|
||||
// Socket not valid, ignore
|
||||
} else if (mg_tls_pending(c) > 0) {
|
||||
} else if (c->rtls.len > 0) {
|
||||
c->is_readable = 1;
|
||||
} else {
|
||||
if (fds[n].revents & POLLERR) {
|
||||
@@ -541,6 +543,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
|
||||
c->is_readable =
|
||||
(unsigned) (fds[n].revents & (POLLIN | POLLHUP) ? 1 : 0);
|
||||
c->is_writable = (unsigned) (fds[n].revents & POLLOUT ? 1 : 0);
|
||||
if (c->rtls.len > 0) c->is_readable = 1;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
@@ -562,7 +565,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
|
||||
FD_SET(FD(c), &eset);
|
||||
if (can_read(c)) FD_SET(FD(c), &rset);
|
||||
if (can_write(c)) FD_SET(FD(c), &wset);
|
||||
if (mg_tls_pending(c) > 0) tvp = &tv_zero;
|
||||
if (c->rtls.len > 0) tvp = &tv_zero;
|
||||
if (FD(c) > maxfd) maxfd = FD(c);
|
||||
if (c->is_closing) ms = 1;
|
||||
}
|
||||
@@ -584,7 +587,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
|
||||
} else {
|
||||
c->is_readable = FD(c) != MG_INVALID_SOCKET && FD_ISSET(FD(c), &rset);
|
||||
c->is_writable = FD(c) != MG_INVALID_SOCKET && FD_ISSET(FD(c), &wset);
|
||||
if (mg_tls_pending(c) > 0) c->is_readable = 1;
|
||||
if (c->rtls.len > 0) c->is_readable = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -692,10 +695,11 @@ void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
|
||||
long n = 0;
|
||||
mg_call(c, MG_EV_READ, &n);
|
||||
}
|
||||
MG_VERBOSE(("%lu %c%c %c%c%c%c%c", c->id, c->is_readable ? 'r' : '-',
|
||||
MG_VERBOSE(("%lu %c%c %c%c%c%c%c %lu %lu", c->id, c->is_readable ? 'r' : '-',
|
||||
c->is_writable ? 'w' : '-', c->is_tls ? 'T' : 't',
|
||||
c->is_connecting ? 'C' : 'c', c->is_tls_hs ? 'H' : 'h',
|
||||
c->is_resolving ? 'R' : 'r', c->is_closing ? 'C' : 'c'));
|
||||
c->is_resolving ? 'R' : 'r', c->is_closing ? 'C' : 'c',
|
||||
mg_tls_pending(c), c->rtls.len));
|
||||
if (c->is_resolving || c->is_closing) {
|
||||
// Do nothing
|
||||
} else if (c->is_listening && c->is_udp == 0) {
|
||||
|
||||
Reference in new issue
Block a user