Skip to content

Commit

Permalink
Fix #2619 - use mg_tls_pending() API to check for buffered TLS data
Browse files Browse the repository at this point in the history
  • Loading branch information
cpq committed Mar 12, 2024
1 parent 2cc18a8 commit 0aa12c1
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 24 deletions.
23 changes: 11 additions & 12 deletions mongoose.c
Original file line number Diff line number Diff line change
Expand Up @@ -7237,8 +7237,8 @@ long mg_io_send(struct mg_connection *c, const void *buf, size_t len) {
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 %ld %d:%d %ld err %d", c->id, c->fd, (int) c->send.len,
(int) c->recv.len, n, MG_SOCK_ERR(n)));
MG_DEBUG(("%lu %ld %lu:%lu:%lu %ld err %d", c->id, c->fd, c->send.len,
c->recv.len, c->rtls.len, n, MG_SOCK_ERR(n)));
iolog(c, (char *) buf, n, false);
return n > 0;
} else {
Expand Down Expand Up @@ -7392,9 +7392,8 @@ static void read_conn(struct mg_connection *c) {
} else {
n = recv_raw(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_SOCK_ERR(n)));
MG_DEBUG(("%lu %ld %lu:%lu:%lu %ld err %d", c->id, c->fd, c->send.len,
c->recv.len, c->rtls.len, n, MG_SOCK_ERR(n)));
iolog(c, buf, n, true);
}
}
Expand Down Expand Up @@ -7582,7 +7581,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 (c->rtls.len > 0) ms = 1, c->is_readable = 1;
if (mg_tls_pending(c) > 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 @@ -7598,7 +7597,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;
if (mg_tls_pending(c) > 0) c->is_readable = 1;
}
}
(void) skip_iotest;
Expand All @@ -7612,7 +7611,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 (c->rtls.len > 0) {
} else if (mg_tls_pending(c) > 0) {
ms = 1; // Don't wait if TLS is ready
} else {
fds[n].fd = FD(c);
Expand All @@ -7634,7 +7633,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 (c->rtls.len > 0) {
} else if (mg_tls_pending(c) > 0) {
c->is_readable = 1;
} else {
if (fds[n].revents & POLLERR) {
Expand All @@ -7643,7 +7642,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;
if (mg_tls_pending(c) > 0) c->is_readable = 1;
}
n++;
}
Expand All @@ -7665,7 +7664,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 (c->rtls.len > 0) tvp = &tv_zero;
if (mg_tls_pending(c) > 0) tvp = &tv_zero;
if (FD(c) > maxfd) maxfd = FD(c);
if (c->is_closing) ms = 1;
}
Expand All @@ -7687,7 +7686,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 (c->rtls.len > 0) c->is_readable = 1;
if (mg_tls_pending(c) > 0) c->is_readable = 1;
}
}
#endif
Expand Down
23 changes: 11 additions & 12 deletions src/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ long mg_io_send(struct mg_connection *c, const void *buf, size_t len) {
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 %ld %d:%d %ld err %d", c->id, c->fd, (int) c->send.len,
(int) c->recv.len, n, MG_SOCK_ERR(n)));
MG_DEBUG(("%lu %ld %lu:%lu:%lu %ld err %d", c->id, c->fd, c->send.len,
c->recv.len, c->rtls.len, n, MG_SOCK_ERR(n)));
iolog(c, (char *) buf, n, false);
return n > 0;
} else {
Expand Down Expand Up @@ -291,9 +291,8 @@ static void read_conn(struct mg_connection *c) {
} else {
n = recv_raw(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_SOCK_ERR(n)));
MG_DEBUG(("%lu %ld %lu:%lu:%lu %ld err %d", c->id, c->fd, c->send.len,
c->recv.len, c->rtls.len, n, MG_SOCK_ERR(n)));
iolog(c, buf, n, true);
}
}
Expand Down Expand Up @@ -481,7 +480,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 (c->rtls.len > 0) ms = 1, c->is_readable = 1;
if (mg_tls_pending(c) > 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,7 +496,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;
if (mg_tls_pending(c) > 0) c->is_readable = 1;
}
}
(void) skip_iotest;
Expand All @@ -511,7 +510,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 (c->rtls.len > 0) {
} else if (mg_tls_pending(c) > 0) {
ms = 1; // Don't wait if TLS is ready
} else {
fds[n].fd = FD(c);
Expand All @@ -533,7 +532,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 (c->rtls.len > 0) {
} else if (mg_tls_pending(c) > 0) {
c->is_readable = 1;
} else {
if (fds[n].revents & POLLERR) {
Expand All @@ -542,7 +541,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;
if (mg_tls_pending(c) > 0) c->is_readable = 1;
}
n++;
}
Expand All @@ -564,7 +563,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 (c->rtls.len > 0) tvp = &tv_zero;
if (mg_tls_pending(c) > 0) tvp = &tv_zero;
if (FD(c) > maxfd) maxfd = FD(c);
if (c->is_closing) ms = 1;
}
Expand All @@ -586,7 +585,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 (c->rtls.len > 0) c->is_readable = 1;
if (mg_tls_pending(c) > 0) c->is_readable = 1;
}
}
#endif
Expand Down
8 changes: 8 additions & 0 deletions test/unit_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1210,6 +1210,7 @@ static void test_tls(void) {
const char *url = "https://127.0.0.1:12347";
char buf[FETCH_BUF_SIZE];
struct mg_tls_opts opts;
struct mg_str data = mg_unpacked("/Makefile");
memset(&opts, 0, sizeof(opts));
// opts.ca = mg_str(s_tls_ca);
opts.cert = mg_str(s_tls_cert);
Expand All @@ -1220,6 +1221,13 @@ static void test_tls(void) {
ASSERT(fetch(&mgr, buf, url, "GET /a.txt HTTP/1.0\n\n") == 200);
// MG_INFO(("%s", buf));
ASSERT(cmpbody(buf, "hello\n") == 0);
// POST a larger file, make sure we drain TLS buffers and read all, #2619
ASSERT(data.ptr != NULL && data.len > 0);
ASSERT(fetch(&mgr, buf, url,
"POST /foo/bar HTTP/1.0\n"
"Content-Length: %lu\n\n"
"%s",
data.len, data.ptr) == 200);
mg_mgr_free(&mgr);
ASSERT(mgr.conns == NULL);
#endif
Expand Down

0 comments on commit 0aa12c1

Please sign in to comment.