mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-17 10:49:47 +00:00
6 files changed
+160
-128
No files matched your search
+78
-62
@@ -12276,8 +12276,10 @@ static void setlocaddr(MG_SOCKET_TYPE fd, struct mg_addr *addr) {
|
||||
}
|
||||
|
||||
// Get the local 'addr' the stack will use to connect to 'to'
|
||||
void mg_getlocaddr(struct mg_connection *c, struct mg_addr *to, struct mg_addr *addr);
|
||||
void mg_getlocaddr(struct mg_connection *c, struct mg_addr *to, struct mg_addr *addr) {
|
||||
void mg_getlocaddr(struct mg_connection *c, struct mg_addr *to,
|
||||
struct mg_addr *addr);
|
||||
void mg_getlocaddr(struct mg_connection *c, struct mg_addr *to,
|
||||
struct mg_addr *addr) {
|
||||
union usa usa;
|
||||
socklen_t slen;
|
||||
MG_SOCKET_TYPE fd;
|
||||
@@ -12297,7 +12299,6 @@ void mg_getlocaddr(struct mg_connection *c, struct mg_addr *to, struct mg_addr *
|
||||
closesocket(fd);
|
||||
}
|
||||
|
||||
|
||||
static void iolog(struct mg_connection *c, char *buf, long n, bool r) {
|
||||
if (n == MG_IO_WAIT) {
|
||||
// Do nothing
|
||||
@@ -12335,7 +12336,7 @@ long mg_io_send(struct mg_connection *c, const void *buf, size_t len) {
|
||||
}
|
||||
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; // MbedTLS, see #1507
|
||||
if (MG_SOCK_RESET(n)) return MG_IO_ERR; // See #1507, #3031
|
||||
if (n <= 0) return MG_IO_ERR;
|
||||
return n;
|
||||
}
|
||||
@@ -12485,7 +12486,7 @@ static long recv_raw(struct mg_connection *c, void *buf, size_t len) {
|
||||
}
|
||||
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; // MbedTLS, see #1507
|
||||
if (MG_SOCK_RESET(n)) return MG_IO_ERR; // See #1507, #3031
|
||||
if (n <= 0) return MG_IO_ERR;
|
||||
return n;
|
||||
}
|
||||
@@ -12506,42 +12507,40 @@ static bool ioalloc(struct mg_connection *c, struct mg_iobuf *io) {
|
||||
// NOTE(lsm): do only one iteration of reads, cause some systems
|
||||
// (e.g. FreeRTOS stack) return 0 instead of -1/EWOULDBLOCK when no data
|
||||
static void read_conn(struct mg_connection *c) {
|
||||
if (ioalloc(c, &c->recv)) {
|
||||
char *buf = (char *) &c->recv.buf[c->recv.len];
|
||||
size_t len = c->recv.size - c->recv.len;
|
||||
long n = -1;
|
||||
if (c->is_tls) {
|
||||
// Do not read to the raw TLS buffer if it already has enough.
|
||||
// This is to prevent overflowing c->rtls if our reads are slow
|
||||
long m;
|
||||
if (c->rtls.len < 16 * 1024 + 40) { // TLS record, header, MAC, padding
|
||||
if (!ioalloc(c, &c->rtls)) return;
|
||||
n = recv_raw(c, (char *) &c->rtls.buf[c->rtls.len],
|
||||
c->rtls.size - c->rtls.len);
|
||||
if (n > 0) c->rtls.len += (size_t) n;
|
||||
}
|
||||
// there can still be > 16K from last iteration, always mg_tls_recv()
|
||||
m = c->is_tls_hs ? (long) MG_IO_WAIT : mg_tls_recv(c, buf, len);
|
||||
if (n == MG_IO_ERR || n == MG_IO_RESET) { // Windows, see #3031
|
||||
if (c->rtls.len == 0 || m < 0) {
|
||||
// Close only when we have fully drained both rtls and TLS buffers
|
||||
c->is_closing = 1; // or there's nothing we can do about it.
|
||||
if (m < 0) m = MG_IO_ERR; // but return last record data, see #3104
|
||||
} else { // see #2885
|
||||
// TLS buffer is capped to max record size, even though, there can
|
||||
// be more than one record, give TLS a chance to process them.
|
||||
}
|
||||
} else if (c->is_tls_hs) {
|
||||
long n = MG_IO_WAIT;
|
||||
if (ioalloc(c, &c->recv) == false) return; // Oopsie poopsie, OOM
|
||||
if (c->is_tls) {
|
||||
size_t rtls = c->rtls.len, pending = mg_tls_pending(c);
|
||||
long m = MG_IO_WAIT;
|
||||
if (c->rtls.len < 16 * 1024 + 40) { // TLS record, header, MAC, padding
|
||||
if (!ioalloc(c, &c->rtls)) return;
|
||||
n = recv_raw(c, (char *) &c->rtls.buf[c->rtls.len],
|
||||
c->rtls.size - c->rtls.len);
|
||||
if (n > 0) c->rtls.len += (size_t) n;
|
||||
}
|
||||
// There can still be > 16K from last iteration, always mg_tls_recv()
|
||||
if (c->is_tls_hs) {
|
||||
if (n != MG_IO_ERR || c->rtls.len > 0 || pending > 0) {
|
||||
mg_tls_handshake(c);
|
||||
}
|
||||
n = m;
|
||||
} else {
|
||||
n = recv_raw(c, buf, len);
|
||||
m = mg_tls_recv(c, &c->recv.buf[c->recv.len], c->recv.size - c->recv.len);
|
||||
}
|
||||
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);
|
||||
if (n == MG_IO_ERR &&
|
||||
(m == MG_IO_ERR || (c->rtls.len == 0 && mg_tls_pending(c) == 0) ||
|
||||
(c->is_tls_hs && c->rtls.len == rtls &&
|
||||
mg_tls_pending(c) == pending))) {
|
||||
// Close only when we have fully drained both rtls and TLS buffers
|
||||
c->is_closing = 1; // or there's nothing we can do about it.
|
||||
if (m < 0) m = MG_IO_ERR; // but return last record data, see #3104
|
||||
}
|
||||
n = m;
|
||||
} else {
|
||||
n = recv_raw(c, &c->recv.buf[c->recv.len], c->recv.size - c->recv.len);
|
||||
}
|
||||
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 *) &c->recv.buf[c->recv.len], n, true);
|
||||
}
|
||||
|
||||
static void write_conn(struct mg_connection *c) {
|
||||
@@ -12682,7 +12681,7 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
|
||||
setsockopts(c);
|
||||
c->is_accepted = 1;
|
||||
c->is_hexdumping = lsn->is_hexdumping;
|
||||
setlocaddr(fd, &c->loc); // set local addr to where the client connected to
|
||||
setlocaddr(fd, &c->loc); // set local addr to where the client connected to
|
||||
c->pfn = lsn->pfn;
|
||||
c->pfn_data = lsn->pfn_data;
|
||||
c->fn = lsn->fn;
|
||||
@@ -18595,7 +18594,7 @@ static int mg_net_send(void *ctx, const unsigned char *buf, size_t len) {
|
||||
long n = mg_io_send((struct mg_connection *) ctx, buf, len);
|
||||
MG_VERBOSE(("%lu n=%ld e=%d", ((struct mg_connection *) ctx)->id, n, errno));
|
||||
if (n == MG_IO_WAIT) return MBEDTLS_ERR_SSL_WANT_WRITE;
|
||||
if (n == MG_IO_RESET) return MBEDTLS_ERR_NET_CONN_RESET;
|
||||
// if (n == MG_IO_RESET) return MBEDTLS_ERR_NET_CONN_RESET;
|
||||
if (n == MG_IO_ERR) return MBEDTLS_ERR_NET_SEND_FAILED;
|
||||
return (int) n;
|
||||
}
|
||||
@@ -18603,8 +18602,8 @@ static int mg_net_send(void *ctx, const unsigned char *buf, size_t len) {
|
||||
static int mg_net_recv(void *ctx, unsigned char *buf, size_t len) {
|
||||
long n = mg_io_recv((struct mg_connection *) ctx, buf, len);
|
||||
MG_VERBOSE(("%lu n=%ld", ((struct mg_connection *) ctx)->id, n));
|
||||
if (n == MG_IO_WAIT) return MBEDTLS_ERR_SSL_WANT_WRITE;
|
||||
if (n == MG_IO_RESET) return MBEDTLS_ERR_NET_CONN_RESET;
|
||||
if (n == MG_IO_WAIT) return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
// if (n == MG_IO_RESET) return MBEDTLS_ERR_NET_CONN_RESET;
|
||||
if (n == MG_IO_ERR) return MBEDTLS_ERR_NET_RECV_FAILED;
|
||||
return (int) n;
|
||||
}
|
||||
@@ -18642,11 +18641,6 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) {
|
||||
if (c->is_listening) goto fail;
|
||||
MG_DEBUG(("%lu Setting TLS", c->id));
|
||||
MG_PROF_ADD(c, "mbedtls_init_start");
|
||||
#if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000 && \
|
||||
defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
psa_crypto_init(); // https://github.com/Mbed-TLS/mbedtls/issues/9072#issuecomment-2084845711
|
||||
// this initializes global resources and then just returns when called again
|
||||
#endif
|
||||
mbedtls_ssl_init(&tls->ssl);
|
||||
mbedtls_ssl_config_init(&tls->conf);
|
||||
mbedtls_x509_crt_init(&tls->ca);
|
||||
@@ -18698,9 +18692,11 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) {
|
||||
}
|
||||
|
||||
#ifdef MBEDTLS_SSL_SESSION_TICKETS
|
||||
mbedtls_ssl_conf_session_tickets_cb(
|
||||
&tls->conf, mbedtls_ssl_ticket_write, mbedtls_ssl_ticket_parse,
|
||||
&((struct mg_tls_ctx *) c->mgr->tls_ctx)->tickets);
|
||||
if (!c->is_client && c->mgr->tls_ctx != NULL) {
|
||||
mbedtls_ssl_conf_session_tickets_cb(
|
||||
&tls->conf, mbedtls_ssl_ticket_write, mbedtls_ssl_ticket_parse,
|
||||
&((struct mg_tls_ctx *) c->mgr->tls_ctx)->tickets);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((rc = mbedtls_ssl_setup(&tls->ssl, &tls->conf)) != 0) {
|
||||
@@ -18744,6 +18740,12 @@ long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
|
||||
tls->throttled_len) /* flush old data */
|
||||
: mbedtls_ssl_write(&tls->ssl, (unsigned char *) buf,
|
||||
len); // encrypt current data
|
||||
#if defined(MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET)
|
||||
if (n == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) {
|
||||
c->is_tls_throttled = was_throttled;
|
||||
return MG_IO_WAIT;
|
||||
}
|
||||
#endif
|
||||
c->is_tls_throttled =
|
||||
(n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE);
|
||||
if (was_throttled) return MG_IO_WAIT; // flushed throttled data instead
|
||||
@@ -18762,32 +18764,46 @@ 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);
|
||||
#if defined(MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET)
|
||||
if (n == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) return;
|
||||
#endif
|
||||
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 *) mg_calloc(1, sizeof(*ctx));
|
||||
if (ctx == NULL) {
|
||||
MG_ERROR(("TLS context init OOM"));
|
||||
} else {
|
||||
#if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000 && \
|
||||
defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
psa_crypto_init(); // Initializes global PSA resources, no-op if already done
|
||||
#endif
|
||||
#ifdef MBEDTLS_SSL_SESSION_TICKETS
|
||||
int rc;
|
||||
mbedtls_ssl_ticket_init(&ctx->tickets);
|
||||
{
|
||||
struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) mg_calloc(1, sizeof(*ctx));
|
||||
if (ctx == NULL) {
|
||||
MG_ERROR(("TLS context init OOM"));
|
||||
} else {
|
||||
int rc;
|
||||
mbedtls_ssl_ticket_init(&ctx->tickets);
|
||||
#if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x04000000
|
||||
if ((rc = mbedtls_ssl_ticket_setup(&ctx->tickets, PSA_ALG_GCM,
|
||||
PSA_KEY_TYPE_AES, 128, 86400))
|
||||
rc = mbedtls_ssl_ticket_setup(&ctx->tickets, PSA_ALG_GCM,
|
||||
PSA_KEY_TYPE_AES, 128, 86400);
|
||||
#else
|
||||
if ((rc = mbedtls_ssl_ticket_setup(&ctx->tickets, mg_mbed_rng, NULL,
|
||||
MBEDTLS_CIPHER_AES_128_GCM, 86400))
|
||||
rc = mbedtls_ssl_ticket_setup(&ctx->tickets, mg_mbed_rng, NULL,
|
||||
MBEDTLS_CIPHER_AES_128_GCM, 86400);
|
||||
#endif
|
||||
!= 0) {
|
||||
MG_ERROR((" mbedtls_ssl_ticket_setup %#x", -rc));
|
||||
if (rc != 0) {
|
||||
MG_ERROR((" mbedtls_ssl_ticket_setup %#x", -rc));
|
||||
mbedtls_ssl_ticket_free(&ctx->tickets);
|
||||
mg_free(ctx);
|
||||
} else {
|
||||
mgr->tls_ctx = ctx;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
mgr->tls_ctx = ctx;
|
||||
}
|
||||
#else
|
||||
(void) mgr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void mg_tls_ctx_free(struct mg_mgr *mgr) {
|
||||
|
||||
+1
-1
@@ -1904,7 +1904,7 @@ void mg_tls_ctx_free(struct mg_mgr *);
|
||||
#define MG_IS_DER(buf) (((uint8_t *) (buf))[0] == 0x30) // DER begins with 0x30
|
||||
|
||||
// Low-level IO primives used by TLS layer
|
||||
enum { MG_IO_ERR = -1, MG_IO_WAIT = -2, MG_IO_RESET = -3 };
|
||||
enum { MG_IO_ERR = -1, MG_IO_WAIT = -2 };
|
||||
long mg_io_send(struct mg_connection *c, const void *buf, size_t len);
|
||||
long mg_io_recv(struct mg_connection *c, void *buf, size_t len);
|
||||
#ifndef TLS_X15519_H
|
||||
|
||||
+36
-37
@@ -94,8 +94,10 @@ static void setlocaddr(MG_SOCKET_TYPE fd, struct mg_addr *addr) {
|
||||
}
|
||||
|
||||
// Get the local 'addr' the stack will use to connect to 'to'
|
||||
void mg_getlocaddr(struct mg_connection *c, struct mg_addr *to, struct mg_addr *addr);
|
||||
void mg_getlocaddr(struct mg_connection *c, struct mg_addr *to, struct mg_addr *addr) {
|
||||
void mg_getlocaddr(struct mg_connection *c, struct mg_addr *to,
|
||||
struct mg_addr *addr);
|
||||
void mg_getlocaddr(struct mg_connection *c, struct mg_addr *to,
|
||||
struct mg_addr *addr) {
|
||||
union usa usa;
|
||||
socklen_t slen;
|
||||
MG_SOCKET_TYPE fd;
|
||||
@@ -115,7 +117,6 @@ void mg_getlocaddr(struct mg_connection *c, struct mg_addr *to, struct mg_addr *
|
||||
closesocket(fd);
|
||||
}
|
||||
|
||||
|
||||
static void iolog(struct mg_connection *c, char *buf, long n, bool r) {
|
||||
if (n == MG_IO_WAIT) {
|
||||
// Do nothing
|
||||
@@ -153,7 +154,7 @@ long mg_io_send(struct mg_connection *c, const void *buf, size_t len) {
|
||||
}
|
||||
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; // MbedTLS, see #1507
|
||||
if (MG_SOCK_RESET(n)) return MG_IO_ERR; // See #1507, #3031
|
||||
if (n <= 0) return MG_IO_ERR;
|
||||
return n;
|
||||
}
|
||||
@@ -303,7 +304,7 @@ static long recv_raw(struct mg_connection *c, void *buf, size_t len) {
|
||||
}
|
||||
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; // MbedTLS, see #1507
|
||||
if (MG_SOCK_RESET(n)) return MG_IO_ERR; // See #1507, #3031
|
||||
if (n <= 0) return MG_IO_ERR;
|
||||
return n;
|
||||
}
|
||||
@@ -324,42 +325,40 @@ static bool ioalloc(struct mg_connection *c, struct mg_iobuf *io) {
|
||||
// NOTE(lsm): do only one iteration of reads, cause some systems
|
||||
// (e.g. FreeRTOS stack) return 0 instead of -1/EWOULDBLOCK when no data
|
||||
static void read_conn(struct mg_connection *c) {
|
||||
if (ioalloc(c, &c->recv)) {
|
||||
char *buf = (char *) &c->recv.buf[c->recv.len];
|
||||
size_t len = c->recv.size - c->recv.len;
|
||||
long n = -1;
|
||||
if (c->is_tls) {
|
||||
// Do not read to the raw TLS buffer if it already has enough.
|
||||
// This is to prevent overflowing c->rtls if our reads are slow
|
||||
long m;
|
||||
if (c->rtls.len < 16 * 1024 + 40) { // TLS record, header, MAC, padding
|
||||
if (!ioalloc(c, &c->rtls)) return;
|
||||
n = recv_raw(c, (char *) &c->rtls.buf[c->rtls.len],
|
||||
c->rtls.size - c->rtls.len);
|
||||
if (n > 0) c->rtls.len += (size_t) n;
|
||||
}
|
||||
// there can still be > 16K from last iteration, always mg_tls_recv()
|
||||
m = c->is_tls_hs ? (long) MG_IO_WAIT : mg_tls_recv(c, buf, len);
|
||||
if (n == MG_IO_ERR || n == MG_IO_RESET) { // Windows, see #3031
|
||||
if (c->rtls.len == 0 || m < 0) {
|
||||
// Close only when we have fully drained both rtls and TLS buffers
|
||||
c->is_closing = 1; // or there's nothing we can do about it.
|
||||
if (m < 0) m = MG_IO_ERR; // but return last record data, see #3104
|
||||
} else { // see #2885
|
||||
// TLS buffer is capped to max record size, even though, there can
|
||||
// be more than one record, give TLS a chance to process them.
|
||||
}
|
||||
} else if (c->is_tls_hs) {
|
||||
long n = MG_IO_WAIT;
|
||||
if (ioalloc(c, &c->recv) == false) return; // Oopsie poopsie, OOM
|
||||
if (c->is_tls) {
|
||||
size_t rtls = c->rtls.len, pending = mg_tls_pending(c);
|
||||
long m = MG_IO_WAIT;
|
||||
if (c->rtls.len < 16 * 1024 + 40) { // TLS record, header, MAC, padding
|
||||
if (!ioalloc(c, &c->rtls)) return;
|
||||
n = recv_raw(c, (char *) &c->rtls.buf[c->rtls.len],
|
||||
c->rtls.size - c->rtls.len);
|
||||
if (n > 0) c->rtls.len += (size_t) n;
|
||||
}
|
||||
// There can still be > 16K from last iteration, always mg_tls_recv()
|
||||
if (c->is_tls_hs) {
|
||||
if (n != MG_IO_ERR || c->rtls.len > 0 || pending > 0) {
|
||||
mg_tls_handshake(c);
|
||||
}
|
||||
n = m;
|
||||
} else {
|
||||
n = recv_raw(c, buf, len);
|
||||
m = mg_tls_recv(c, &c->recv.buf[c->recv.len], c->recv.size - c->recv.len);
|
||||
}
|
||||
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);
|
||||
if (n == MG_IO_ERR &&
|
||||
(m == MG_IO_ERR || (c->rtls.len == 0 && mg_tls_pending(c) == 0) ||
|
||||
(c->is_tls_hs && c->rtls.len == rtls &&
|
||||
mg_tls_pending(c) == pending))) {
|
||||
// Close only when we have fully drained both rtls and TLS buffers
|
||||
c->is_closing = 1; // or there's nothing we can do about it.
|
||||
if (m < 0) m = MG_IO_ERR; // but return last record data, see #3104
|
||||
}
|
||||
n = m;
|
||||
} else {
|
||||
n = recv_raw(c, &c->recv.buf[c->recv.len], c->recv.size - c->recv.len);
|
||||
}
|
||||
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 *) &c->recv.buf[c->recv.len], n, true);
|
||||
}
|
||||
|
||||
static void write_conn(struct mg_connection *c) {
|
||||
@@ -500,7 +499,7 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
|
||||
setsockopts(c);
|
||||
c->is_accepted = 1;
|
||||
c->is_hexdumping = lsn->is_hexdumping;
|
||||
setlocaddr(fd, &c->loc); // set local addr to where the client connected to
|
||||
setlocaddr(fd, &c->loc); // set local addr to where the client connected to
|
||||
c->pfn = lsn->pfn;
|
||||
c->pfn_data = lsn->pfn_data;
|
||||
c->fn = lsn->fn;
|
||||
|
||||
@@ -37,6 +37,6 @@ void mg_tls_ctx_free(struct mg_mgr *);
|
||||
#define MG_IS_DER(buf) (((uint8_t *) (buf))[0] == 0x30) // DER begins with 0x30
|
||||
|
||||
// Low-level IO primives used by TLS layer
|
||||
enum { MG_IO_ERR = -1, MG_IO_WAIT = -2, MG_IO_RESET = -3 };
|
||||
enum { MG_IO_ERR = -1, MG_IO_WAIT = -2 };
|
||||
long mg_io_send(struct mg_connection *c, const void *buf, size_t len);
|
||||
long mg_io_recv(struct mg_connection *c, void *buf, size_t len);
|
||||
+42
-25
@@ -75,7 +75,7 @@ static int mg_net_send(void *ctx, const unsigned char *buf, size_t len) {
|
||||
long n = mg_io_send((struct mg_connection *) ctx, buf, len);
|
||||
MG_VERBOSE(("%lu n=%ld e=%d", ((struct mg_connection *) ctx)->id, n, errno));
|
||||
if (n == MG_IO_WAIT) return MBEDTLS_ERR_SSL_WANT_WRITE;
|
||||
if (n == MG_IO_RESET) return MBEDTLS_ERR_NET_CONN_RESET;
|
||||
// if (n == MG_IO_RESET) return MBEDTLS_ERR_NET_CONN_RESET;
|
||||
if (n == MG_IO_ERR) return MBEDTLS_ERR_NET_SEND_FAILED;
|
||||
return (int) n;
|
||||
}
|
||||
@@ -83,8 +83,8 @@ static int mg_net_send(void *ctx, const unsigned char *buf, size_t len) {
|
||||
static int mg_net_recv(void *ctx, unsigned char *buf, size_t len) {
|
||||
long n = mg_io_recv((struct mg_connection *) ctx, buf, len);
|
||||
MG_VERBOSE(("%lu n=%ld", ((struct mg_connection *) ctx)->id, n));
|
||||
if (n == MG_IO_WAIT) return MBEDTLS_ERR_SSL_WANT_WRITE;
|
||||
if (n == MG_IO_RESET) return MBEDTLS_ERR_NET_CONN_RESET;
|
||||
if (n == MG_IO_WAIT) return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
// if (n == MG_IO_RESET) return MBEDTLS_ERR_NET_CONN_RESET;
|
||||
if (n == MG_IO_ERR) return MBEDTLS_ERR_NET_RECV_FAILED;
|
||||
return (int) n;
|
||||
}
|
||||
@@ -122,11 +122,6 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) {
|
||||
if (c->is_listening) goto fail;
|
||||
MG_DEBUG(("%lu Setting TLS", c->id));
|
||||
MG_PROF_ADD(c, "mbedtls_init_start");
|
||||
#if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000 && \
|
||||
defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
psa_crypto_init(); // https://github.com/Mbed-TLS/mbedtls/issues/9072#issuecomment-2084845711
|
||||
// this initializes global resources and then just returns when called again
|
||||
#endif
|
||||
mbedtls_ssl_init(&tls->ssl);
|
||||
mbedtls_ssl_config_init(&tls->conf);
|
||||
mbedtls_x509_crt_init(&tls->ca);
|
||||
@@ -178,9 +173,11 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) {
|
||||
}
|
||||
|
||||
#ifdef MBEDTLS_SSL_SESSION_TICKETS
|
||||
mbedtls_ssl_conf_session_tickets_cb(
|
||||
&tls->conf, mbedtls_ssl_ticket_write, mbedtls_ssl_ticket_parse,
|
||||
&((struct mg_tls_ctx *) c->mgr->tls_ctx)->tickets);
|
||||
if (!c->is_client && c->mgr->tls_ctx != NULL) {
|
||||
mbedtls_ssl_conf_session_tickets_cb(
|
||||
&tls->conf, mbedtls_ssl_ticket_write, mbedtls_ssl_ticket_parse,
|
||||
&((struct mg_tls_ctx *) c->mgr->tls_ctx)->tickets);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((rc = mbedtls_ssl_setup(&tls->ssl, &tls->conf)) != 0) {
|
||||
@@ -224,6 +221,12 @@ long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
|
||||
tls->throttled_len) /* flush old data */
|
||||
: mbedtls_ssl_write(&tls->ssl, (unsigned char *) buf,
|
||||
len); // encrypt current data
|
||||
#if defined(MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET)
|
||||
if (n == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) {
|
||||
c->is_tls_throttled = was_throttled;
|
||||
return MG_IO_WAIT;
|
||||
}
|
||||
#endif
|
||||
c->is_tls_throttled =
|
||||
(n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE);
|
||||
if (was_throttled) return MG_IO_WAIT; // flushed throttled data instead
|
||||
@@ -242,32 +245,46 @@ 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);
|
||||
#if defined(MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET)
|
||||
if (n == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) return;
|
||||
#endif
|
||||
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 *) mg_calloc(1, sizeof(*ctx));
|
||||
if (ctx == NULL) {
|
||||
MG_ERROR(("TLS context init OOM"));
|
||||
} else {
|
||||
#if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000 && \
|
||||
defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
psa_crypto_init(); // Initializes global PSA resources, no-op if already done
|
||||
#endif
|
||||
#ifdef MBEDTLS_SSL_SESSION_TICKETS
|
||||
int rc;
|
||||
mbedtls_ssl_ticket_init(&ctx->tickets);
|
||||
{
|
||||
struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) mg_calloc(1, sizeof(*ctx));
|
||||
if (ctx == NULL) {
|
||||
MG_ERROR(("TLS context init OOM"));
|
||||
} else {
|
||||
int rc;
|
||||
mbedtls_ssl_ticket_init(&ctx->tickets);
|
||||
#if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x04000000
|
||||
if ((rc = mbedtls_ssl_ticket_setup(&ctx->tickets, PSA_ALG_GCM,
|
||||
PSA_KEY_TYPE_AES, 128, 86400))
|
||||
rc = mbedtls_ssl_ticket_setup(&ctx->tickets, PSA_ALG_GCM,
|
||||
PSA_KEY_TYPE_AES, 128, 86400);
|
||||
#else
|
||||
if ((rc = mbedtls_ssl_ticket_setup(&ctx->tickets, mg_mbed_rng, NULL,
|
||||
MBEDTLS_CIPHER_AES_128_GCM, 86400))
|
||||
rc = mbedtls_ssl_ticket_setup(&ctx->tickets, mg_mbed_rng, NULL,
|
||||
MBEDTLS_CIPHER_AES_128_GCM, 86400);
|
||||
#endif
|
||||
!= 0) {
|
||||
MG_ERROR((" mbedtls_ssl_ticket_setup %#x", -rc));
|
||||
if (rc != 0) {
|
||||
MG_ERROR((" mbedtls_ssl_ticket_setup %#x", -rc));
|
||||
mbedtls_ssl_ticket_free(&ctx->tickets);
|
||||
mg_free(ctx);
|
||||
} else {
|
||||
mgr->tls_ctx = ctx;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
mgr->tls_ctx = ctx;
|
||||
}
|
||||
#else
|
||||
(void) mgr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void mg_tls_ctx_free(struct mg_mgr *mgr) {
|
||||
|
||||
+2
-2
@@ -622,7 +622,7 @@ static void test_mqtt_basic(void) {
|
||||
// Connect with empty client ID, no options, ergo MQTT = 3.1.1
|
||||
mg_mgr_init(&mgr);
|
||||
c = mg_mqtt_connect(&mgr, url, NULL, mqtt_cb, &test_data);
|
||||
for (i = 0; i < 300 && mbuf[0] == 0; i++) mg_mgr_poll(&mgr, 10);
|
||||
for (i = 0; i < 1000 && mbuf[0] == 0; i++) mg_mgr_poll(&mgr, 10);
|
||||
if (mbuf[0] != 'X') MG_INFO(("[%s]", mbuf));
|
||||
ASSERT(mbuf[0] == 'X');
|
||||
ASSERT(test_data.flags == 0);
|
||||
@@ -711,7 +711,7 @@ static void test_mqtt_ver(uint8_t mqtt_version) {
|
||||
opts.message = mg_str("mg_will_messsage");
|
||||
opts.client_id = genstring(client_id, sizeof(client_id));
|
||||
c = mg_mqtt_connect(&mgr, url, &opts, mqtt_cb, &test_data);
|
||||
for (i = 0; i < 500 && mbuf[0] == 0; i++) mg_mgr_poll(&mgr, 10);
|
||||
for (i = 0; i < 1000 && mbuf[0] == 0; i++) mg_mgr_poll(&mgr, 10);
|
||||
if (mbuf[0] != 'X') MG_INFO(("[%s]", mbuf));
|
||||
ASSERT(mbuf[0] == 'X');
|
||||
ASSERT(test_data.flags == 0);
|
||||
|
||||
Reference in new issue
Block a user