Skip to content

Commit

Permalink
Merge pull request #2607 from cesanta/tls
Browse files Browse the repository at this point in the history
Fix #2603: TLS read path
  • Loading branch information
scaprile authored Feb 14, 2024
2 parents daa47e8 + 9172f62 commit 4ab2309
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 18 deletions.
22 changes: 13 additions & 9 deletions mongoose.c
Original file line number Diff line number Diff line change
Expand Up @@ -7192,6 +7192,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;
Expand Down Expand Up @@ -7313,6 +7314,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;
Expand Down Expand Up @@ -7343,8 +7345,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 {
Expand Down Expand Up @@ -7543,7 +7544,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++;
Expand All @@ -7559,6 +7560,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;
Expand All @@ -7572,7 +7574,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);
Expand All @@ -7594,7 +7596,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) {
Expand All @@ -7603,6 +7605,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++;
}
Expand All @@ -7624,7 +7627,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;
}
Expand All @@ -7646,7 +7649,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
Expand Down Expand Up @@ -7754,10 +7757,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) {
Expand Down
22 changes: 13 additions & 9 deletions src/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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++;
Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -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) {
Expand All @@ -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++;
}
Expand All @@ -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;
}
Expand All @@ -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
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 4ab2309

Please sign in to comment.