flush TLS buffer

This commit is contained in:
Sergio R. Caprile 2025-05-22 16:20:40 -03:00
parent 5726e680ec
commit 1f48b1ca65
9 changed files with 62 additions and 10 deletions

View File

@ -5383,6 +5383,7 @@ void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
if (c->is_tls && (c->rtls.len > 0 || mg_tls_pending(c) > 0))
handle_tls_recv(c);
if (can_write(c)) write_conn(c);
if (!c->is_listening && c->is_tls && !c->is_tls_hs && c->send.len == 0) mg_tls_flush(c);
if (c->is_draining && c->send.len == 0 && s->ttype != MIP_TTYPE_FIN)
init_closure(c);
// For non-TLS, close immediately upon completing the 3-way closure
@ -9341,11 +9342,10 @@ void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
if (c->is_readable) accept_conn(mgr, c);
} else if (c->is_connecting) {
if (c->is_readable || c->is_writable) connect_conn(c);
//} else if (c->is_tls_hs) {
// if ((c->is_readable || c->is_writable)) mg_tls_handshake(c);
} else {
if (c->is_readable) read_conn(c);
if (c->is_writable) write_conn(c);
if (c->is_tls && !c->is_tls_hs && c->send.len == 0) mg_tls_flush(c);
}
if (c->is_draining && c->send.len == 0) c->is_closing = 1;
@ -12382,6 +12382,7 @@ void mg_tls_handshake(struct mg_connection *c) {
struct tls_data *tls = (struct tls_data *) c->tls;
long n;
if (c->is_client) {
// will clear is_hs when sending last chunk
mg_tls_client_handshake(c);
} else {
mg_tls_server_handshake(c);
@ -12389,7 +12390,8 @@ void mg_tls_handshake(struct mg_connection *c) {
while (tls->send.len > 0 &&
(n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) {
mg_iobuf_del(&tls->send, 0, (size_t) n);
}
} // if last chunk fails to be sent, it will be sent with first app data,
// otherwise, it needs to be flushed
}
static int mg_parse_pem(const struct mg_str pem, const struct mg_str label,
@ -12523,7 +12525,7 @@ long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
while (tls->send.len > 0 &&
(n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) {
mg_iobuf_del(&tls->send, 0, (size_t) n);
}
} // if last chunk fails to be sent, it needs to be flushed
c->is_tls_throttled = (tls->send.len > 0 && n == MG_IO_WAIT);
MG_VERBOSE(("%lu %ld %ld %ld %c %c", c->id, (long) len, (long) tls->send.len,
n, was_throttled ? 'T' : 't', c->is_tls_throttled ? 'T' : 't'));
@ -12565,6 +12567,15 @@ size_t mg_tls_pending(struct mg_connection *c) {
return tls != NULL ? tls->recv_len : 0;
}
void mg_tls_flush(struct mg_connection *c) {
struct tls_data *tls = (struct tls_data *) c->tls;
long n;
while (tls->send.len > 0 &&
(n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) {
mg_iobuf_del(&tls->send, 0, (size_t) n);
}
}
void mg_tls_ctx_init(struct mg_mgr *mgr) {
(void) mgr;
}
@ -13947,6 +13958,9 @@ size_t mg_tls_pending(struct mg_connection *c) {
(void) c;
return 0;
}
void mg_tls_flush(struct mg_connection *c) {
(void) c;
}
void mg_tls_ctx_init(struct mg_mgr *mgr) {
(void) mgr;
}
@ -14164,11 +14178,18 @@ long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
tls->throttled_buf = (unsigned char *)buf; // MbedTLS code actually ignores
tls->throttled_len = len; // these, but let's play API rules
return (long) len; // already encripted that when throttled
}
} // if last chunk fails to be sent, it needs to be flushed
if (n <= 0) return MG_IO_ERR;
return n;
}
void mg_tls_flush(struct mg_connection *c) {
if (c->is_tls_throttled) {
long n = mbedtls_ssl_write(&tls->ssl, tls->throttled_buf, tls->throttled_len);
c->is_tls_throttled = (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE);
}
}
void mg_tls_ctx_init(struct mg_mgr *mgr) {
struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) calloc(1, sizeof(*ctx));
if (ctx == NULL) {
@ -14474,6 +14495,10 @@ long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
return n;
}
void mg_tls_flush(struct mg_connection *c) {
(void) c;
}
void mg_tls_ctx_init(struct mg_mgr *mgr) {
(void) mgr;
}

View File

@ -2424,6 +2424,7 @@ void mg_tls_free(struct mg_connection *);
long mg_tls_send(struct mg_connection *, const void *buf, size_t len);
long mg_tls_recv(struct mg_connection *, void *buf, size_t len);
size_t mg_tls_pending(struct mg_connection *);
void mg_tls_flush(struct mg_connection *);
void mg_tls_handshake(struct mg_connection *);
// Private

View File

@ -1218,6 +1218,7 @@ void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
if (c->is_tls && (c->rtls.len > 0 || mg_tls_pending(c) > 0))
handle_tls_recv(c);
if (can_write(c)) write_conn(c);
if (!c->is_listening && c->is_tls && !c->is_tls_hs && c->send.len == 0) mg_tls_flush(c);
if (c->is_draining && c->send.len == 0 && s->ttype != MIP_TTYPE_FIN)
init_closure(c);
// For non-TLS, close immediately upon completing the 3-way closure

View File

@ -734,11 +734,10 @@ void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
if (c->is_readable) accept_conn(mgr, c);
} else if (c->is_connecting) {
if (c->is_readable || c->is_writable) connect_conn(c);
//} else if (c->is_tls_hs) {
// if ((c->is_readable || c->is_writable)) mg_tls_handshake(c);
} else {
if (c->is_readable) read_conn(c);
if (c->is_writable) write_conn(c);
if (c->is_tls && !c->is_tls_hs && c->send.len == 0) mg_tls_flush(c);
}
if (c->is_draining && c->send.len == 0) c->is_closing = 1;

View File

@ -28,6 +28,7 @@ void mg_tls_free(struct mg_connection *);
long mg_tls_send(struct mg_connection *, const void *buf, size_t len);
long mg_tls_recv(struct mg_connection *, void *buf, size_t len);
size_t mg_tls_pending(struct mg_connection *);
void mg_tls_flush(struct mg_connection *);
void mg_tls_handshake(struct mg_connection *);
// Private

View File

@ -1557,6 +1557,7 @@ void mg_tls_handshake(struct mg_connection *c) {
struct tls_data *tls = (struct tls_data *) c->tls;
long n;
if (c->is_client) {
// will clear is_hs when sending last chunk
mg_tls_client_handshake(c);
} else {
mg_tls_server_handshake(c);
@ -1564,7 +1565,8 @@ void mg_tls_handshake(struct mg_connection *c) {
while (tls->send.len > 0 &&
(n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) {
mg_iobuf_del(&tls->send, 0, (size_t) n);
}
} // if last chunk fails to be sent, it will be sent with first app data,
// otherwise, it needs to be flushed
}
static int mg_parse_pem(const struct mg_str pem, const struct mg_str label,
@ -1698,7 +1700,7 @@ long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
while (tls->send.len > 0 &&
(n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) {
mg_iobuf_del(&tls->send, 0, (size_t) n);
}
} // if last chunk fails to be sent, it needs to be flushed
c->is_tls_throttled = (tls->send.len > 0 && n == MG_IO_WAIT);
MG_VERBOSE(("%lu %ld %ld %ld %c %c", c->id, (long) len, (long) tls->send.len,
n, was_throttled ? 'T' : 't', c->is_tls_throttled ? 'T' : 't'));
@ -1740,6 +1742,15 @@ size_t mg_tls_pending(struct mg_connection *c) {
return tls != NULL ? tls->recv_len : 0;
}
void mg_tls_flush(struct mg_connection *c) {
struct tls_data *tls = (struct tls_data *) c->tls;
long n;
while (tls->send.len > 0 &&
(n = mg_io_send(c, tls->send.buf, tls->send.len)) > 0) {
mg_iobuf_del(&tls->send, 0, (size_t) n);
}
}
void mg_tls_ctx_init(struct mg_mgr *mgr) {
(void) mgr;
}

View File

@ -21,6 +21,9 @@ size_t mg_tls_pending(struct mg_connection *c) {
(void) c;
return 0;
}
void mg_tls_flush(struct mg_connection *c) {
(void) c;
}
void mg_tls_ctx_init(struct mg_mgr *mgr) {
(void) mgr;
}

View File

@ -204,11 +204,18 @@ long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
tls->throttled_buf = (unsigned char *)buf; // MbedTLS code actually ignores
tls->throttled_len = len; // these, but let's play API rules
return (long) len; // already encripted that when throttled
}
} // if last chunk fails to be sent, it needs to be flushed
if (n <= 0) return MG_IO_ERR;
return n;
}
void mg_tls_flush(struct mg_connection *c) {
if (c->is_tls_throttled) {
long n = mbedtls_ssl_write(&tls->ssl, tls->throttled_buf, tls->throttled_len);
c->is_tls_throttled = (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE);
}
}
void mg_tls_ctx_init(struct mg_mgr *mgr) {
struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) calloc(1, sizeof(*ctx));
if (ctx == NULL) {

View File

@ -270,6 +270,10 @@ long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
return n;
}
void mg_tls_flush(struct mg_connection *c) {
(void) c;
}
void mg_tls_ctx_init(struct mg_mgr *mgr) {
(void) mgr;
}