mirror of
https://github.com/cesanta/mongoose.git
synced 2026-11-15 19:13:18 +00:00
Mongoose net_if and ssl_if refactoring
A major cleanup, disentangling net_if and ssl_if. Pulled a lot of common logic into the core and reduced size of net_if implementations. CL: Mongoose net_if and ssl_if refactoring PUBLISHED_FROM=29bd4dcb264a1fd96b3dd164e2d880e1c2c0921e
This commit is contained in:
1 parent
c80f4c5313
commit
3e33e57707
17 files changed
+1358
-2007
No files matched your search
+56
-32
@@ -7,9 +7,12 @@
|
||||
|
||||
#include <mbedtls/debug.h>
|
||||
#include <mbedtls/ecp.h>
|
||||
#include <mbedtls/net.h>
|
||||
#include <mbedtls/platform.h>
|
||||
#include <mbedtls/ssl.h>
|
||||
#include <mbedtls/ssl_internal.h>
|
||||
#include <mbedtls/x509_crt.h>
|
||||
#include <mbedtls/version.h>
|
||||
|
||||
static void mg_ssl_mbed_log(void *ctx, int level, const char *file, int line,
|
||||
const char *str) {
|
||||
@@ -19,6 +22,8 @@ static void mg_ssl_mbed_log(void *ctx, int level, const char *file, int line,
|
||||
cs_level = LL_ERROR;
|
||||
break;
|
||||
case 2:
|
||||
cs_level = LL_INFO;
|
||||
break;
|
||||
case 3:
|
||||
cs_level = LL_DEBUG;
|
||||
break;
|
||||
@@ -38,12 +43,14 @@ struct mg_ssl_if_ctx {
|
||||
mbedtls_pk_context *key;
|
||||
mbedtls_x509_crt *ca_cert;
|
||||
struct mbuf cipher_suites;
|
||||
size_t saved_len;
|
||||
};
|
||||
|
||||
/* Must be provided by the platform. ctx is struct mg_connection. */
|
||||
extern int mg_ssl_if_mbed_random(void *ctx, unsigned char *buf, size_t len);
|
||||
|
||||
void mg_ssl_if_init() {
|
||||
LOG(LL_INFO, ("%s", MBEDTLS_VERSION_STRING_FULL));
|
||||
}
|
||||
|
||||
enum mg_ssl_if_result mg_ssl_if_conn_accept(struct mg_connection *nc,
|
||||
@@ -164,40 +171,41 @@ enum mg_ssl_if_result mg_ssl_if_conn_init(
|
||||
return MG_SSL_OK;
|
||||
}
|
||||
|
||||
#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL
|
||||
int ssl_socket_send(void *ctx, const unsigned char *buf, size_t len);
|
||||
int ssl_socket_recv(void *ctx, unsigned char *buf, size_t len);
|
||||
#else
|
||||
static int ssl_socket_send(void *ctx, const unsigned char *buf, size_t len) {
|
||||
static int mg_ssl_if_mbed_send(void *ctx, const unsigned char *buf,
|
||||
size_t len) {
|
||||
struct mg_connection *nc = (struct mg_connection *) ctx;
|
||||
int n = (int) MG_SEND_FUNC(nc->sock, buf, len, 0);
|
||||
LOG(LL_DEBUG, ("%p %d -> %d", nc, (int) len, n));
|
||||
if (n >= 0) return n;
|
||||
n = mg_get_errno();
|
||||
return ((n == EAGAIN || n == EINPROGRESS) ? MBEDTLS_ERR_SSL_WANT_WRITE : -1);
|
||||
int n = nc->iface->vtable->tcp_send(nc, buf, len);
|
||||
if (n > 0) return n;
|
||||
if (n == 0) return MBEDTLS_ERR_SSL_WANT_WRITE;
|
||||
return MBEDTLS_ERR_NET_SEND_FAILED;
|
||||
}
|
||||
|
||||
static int ssl_socket_recv(void *ctx, unsigned char *buf, size_t len) {
|
||||
static int mg_ssl_if_mbed_recv(void *ctx, unsigned char *buf, size_t len) {
|
||||
struct mg_connection *nc = (struct mg_connection *) ctx;
|
||||
int n = (int) MG_RECV_FUNC(nc->sock, buf, len, 0);
|
||||
LOG(LL_DEBUG, ("%p %d <- %d", nc, (int) len, n));
|
||||
if (n >= 0) return n;
|
||||
n = mg_get_errno();
|
||||
return ((n == EAGAIN || n == EINPROGRESS) ? MBEDTLS_ERR_SSL_WANT_READ : -1);
|
||||
int n = nc->iface->vtable->tcp_recv(nc, buf, len);
|
||||
if (n > 0) return n;
|
||||
if (n == 0) return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
return MBEDTLS_ERR_NET_RECV_FAILED;
|
||||
}
|
||||
#endif
|
||||
|
||||
static enum mg_ssl_if_result mg_ssl_if_mbed_err(struct mg_connection *nc,
|
||||
int ret) {
|
||||
if (ret == MBEDTLS_ERR_SSL_WANT_READ) return MG_SSL_WANT_READ;
|
||||
if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) return MG_SSL_WANT_WRITE;
|
||||
if (ret !=
|
||||
MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { /* CLOSE_NOTIFY = Normal shutdown */
|
||||
LOG(LL_ERROR, ("%p SSL error: %d", nc, ret));
|
||||
enum mg_ssl_if_result res = MG_SSL_OK;
|
||||
if (ret == MBEDTLS_ERR_SSL_WANT_READ) {
|
||||
res = MG_SSL_WANT_READ;
|
||||
} else if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
|
||||
res = MG_SSL_WANT_WRITE;
|
||||
} else if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
|
||||
LOG(LL_DEBUG, ("%p TLS connection closed by peer", nc));
|
||||
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
|
||||
res = MG_SSL_OK;
|
||||
} else {
|
||||
LOG(LL_ERROR, ("%p mbedTLS error: -0x%04x", nc, -ret));
|
||||
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
|
||||
res = MG_SSL_ERROR;
|
||||
}
|
||||
nc->err = ret;
|
||||
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
|
||||
return MG_SSL_ERROR;
|
||||
return res;
|
||||
}
|
||||
|
||||
static void mg_ssl_if_mbed_free_certs_and_keys(struct mg_ssl_if_ctx *ctx) {
|
||||
@@ -228,7 +236,8 @@ enum mg_ssl_if_result mg_ssl_if_handshake(struct mg_connection *nc) {
|
||||
int err;
|
||||
/* If bio is not yet set, do it now. */
|
||||
if (ctx->ssl->p_bio == NULL) {
|
||||
mbedtls_ssl_set_bio(ctx->ssl, nc, ssl_socket_send, ssl_socket_recv, NULL);
|
||||
mbedtls_ssl_set_bio(ctx->ssl, nc, mg_ssl_if_mbed_send, mg_ssl_if_mbed_recv,
|
||||
NULL);
|
||||
}
|
||||
err = mbedtls_ssl_handshake(ctx->ssl);
|
||||
if (err != 0) return mg_ssl_if_mbed_err(nc, err);
|
||||
@@ -254,20 +263,35 @@ enum mg_ssl_if_result mg_ssl_if_handshake(struct mg_connection *nc) {
|
||||
return MG_SSL_OK;
|
||||
}
|
||||
|
||||
int mg_ssl_if_read(struct mg_connection *nc, void *buf, size_t buf_size) {
|
||||
int mg_ssl_if_read(struct mg_connection *nc, void *buf, size_t len) {
|
||||
struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *) nc->ssl_if_data;
|
||||
int n = mbedtls_ssl_read(ctx->ssl, (unsigned char *) buf, buf_size);
|
||||
DBG(("%p %d -> %d", nc, (int) buf_size, n));
|
||||
int n = mbedtls_ssl_read(ctx->ssl, (unsigned char *) buf, len);
|
||||
DBG(("%p %d -> %d", nc, (int) len, n));
|
||||
if (n < 0) return mg_ssl_if_mbed_err(nc, n);
|
||||
if (n == 0) nc->flags |= MG_F_CLOSE_IMMEDIATELY;
|
||||
return n;
|
||||
}
|
||||
|
||||
int mg_ssl_if_write(struct mg_connection *nc, const void *data, size_t len) {
|
||||
int mg_ssl_if_write(struct mg_connection *nc, const void *buf, size_t len) {
|
||||
struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *) nc->ssl_if_data;
|
||||
int n = mbedtls_ssl_write(ctx->ssl, (const unsigned char *) data, len);
|
||||
DBG(("%p %d -> %d", nc, (int) len, n));
|
||||
if (n < 0) return mg_ssl_if_mbed_err(nc, n);
|
||||
/* Per mbedTLS docs, if write returns WANT_READ or WANT_WRITE, the operation
|
||||
* should be retried with the same data and length.
|
||||
* Here we assume that the data being pushed will remain the same but the
|
||||
* amount may grow between calls so we save the length that was used and
|
||||
* retry. The assumption being that the data itself won't change and won't
|
||||
* be removed. */
|
||||
size_t l = len;
|
||||
if (ctx->saved_len > 0 && ctx->saved_len < l) l = ctx->saved_len;
|
||||
int n = mbedtls_ssl_write(ctx->ssl, (const unsigned char *) buf, l);
|
||||
DBG(("%p %d,%d,%d -> %d", nc, (int) len, (int) ctx->saved_len, (int) l, n));
|
||||
if (n < 0) {
|
||||
if (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE) {
|
||||
ctx->saved_len = len;
|
||||
}
|
||||
return mg_ssl_if_mbed_err(nc, n);
|
||||
} else if (n > 0) {
|
||||
ctx->saved_len = 0;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user