Add mbedtls support to MIP

This commit is contained in:
cpq committed 2022-09-09 15:53:42 +01:00
1 parent f76a7e36e8
commit 124ac12150
16 files changed
+446 -303

No files matched your search

+1 -1
View File
@@ -151,7 +151,7 @@ static void dns_cb(struct mg_connection *c, int ev, void *ev_data,
MG_ERROR(("Unexpected DNS response:"));
mg_hexdump(c->recv.buf, c->recv.len);
} else {
MG_VERBOSE(("%s %d", dm.name, dm.resolved));
// MG_VERBOSE(("%s %d", dm.name, dm.resolved));
for (d = (struct dns_data *) c->mgr->active_dns_requests; d != NULL;
d = tmp) {
tmp = d->next;
+1 -1
View File
@@ -197,7 +197,7 @@ static void mqtt_cb(struct mg_connection *c, int ev, void *ev_data,
c->is_closing = 1;
break;
} else if (rc == MQTT_OK) {
MG_VERBOSE(("%p MQTT CMD %d len %d [%.*s]", c->fd, mm.cmd,
MG_VERBOSE(("%lu MQTT CMD %d len %d [%.*s]", c->id, mm.cmd,
(int) mm.dgram.len, (int) mm.data.len, mm.data.ptr));
switch (mm.cmd) {
case MQTT_CMD_CONNACK:
+5
View File
@@ -97,3 +97,8 @@ void mg_close_conn(struct mg_connection *c);
bool mg_open_listener(struct mg_connection *c, const char *url);
struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds,
unsigned flags, void (*fn)(void *), void *arg);
// Low-level IO primives used by TLS layer
enum { MG_IO_ERR = -1, MG_IO_WAIT = -2, MG_IO_RESET = -3 };
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);
+2 -1
View File
@@ -30,7 +30,7 @@ int64_t mg_sntp_parse(const unsigned char *buf, size_t len) {
int64_t t2 = gettimestamp((uint32_t *) &buf[40]);
int64_t t3 = (int64_t) mg_millis();
int64_t delta = (t3 - t0) - (t2 - t1);
MG_DEBUG(("%lld %lld %lld %lld delta:%lld", t0, t1, t2, t3, delta));
MG_VERBOSE(("%lld %lld %lld %lld delta:%lld", t0, t1, t2, t3, delta));
res = t2 + delta / 2;
} else {
MG_ERROR(("unexpected version: %d", version));
@@ -42,6 +42,7 @@ static void sntp_cb(struct mg_connection *c, int ev, void *evd, void *fnd) {
if (ev == MG_EV_READ) {
int64_t milliseconds = mg_sntp_parse(c->recv.buf, c->recv.len);
if (milliseconds > 0) {
MG_INFO(("%lu got time: %lld ms from epoch", c->id, milliseconds));
mg_call(c, MG_EV_SNTP_TIME, (uint64_t *) &milliseconds);
MG_VERBOSE(("%u.%u", (unsigned) (milliseconds / 1000),
(unsigned) (milliseconds % 1000)));
+21 -19
View File
@@ -84,8 +84,7 @@ static void tomgaddr(union usa *usa, struct mg_addr *a, bool is_ip6) {
#endif
}
bool mg_sock_would_block(void);
bool mg_sock_would_block(void) {
static bool mg_sock_would_block(void) {
int err = MG_SOCK_ERRNO;
return err == EINPROGRESS || err == EWOULDBLOCK
#ifndef WINCE
@@ -97,8 +96,7 @@ bool mg_sock_would_block(void) {
;
}
bool mg_sock_conn_reset(void);
bool mg_sock_conn_reset(void) {
static bool mg_sock_conn_reset(void) {
int err = MG_SOCK_ERRNO;
#if MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK
return err == WSAECONNRESET;
@@ -116,9 +114,9 @@ static void setlocaddr(SOCKET fd, struct mg_addr *addr) {
}
static void iolog(struct mg_connection *c, char *buf, long n, bool r) {
if (n == 0) {
if (n == MG_IO_WAIT) {
// Do nothing
} else if (n < 0) {
} else if (n <= 0) {
c->is_closing = 1; // Termination. Don't call mg_error(): #1529
} else if (n > 0) {
if (c->is_hexdumping) {
@@ -151,7 +149,7 @@ static void iolog(struct mg_connection *c, char *buf, long n, bool r) {
}
}
static long mg_sock_send(struct mg_connection *c, const void *buf, size_t len) {
long mg_io_send(struct mg_connection *c, const void *buf, size_t len) {
long n;
if (c->is_udp) {
union usa usa;
@@ -161,15 +159,18 @@ static long mg_sock_send(struct mg_connection *c, const void *buf, size_t len) {
} else {
n = send(FD(c), (char *) buf, len, MSG_NONBLOCKING);
#if MG_ARCH == MG_ARCH_RTX
if (n == BSD_EWOULDBLOCK) return 0;
if (n == BSD_EWOULDBLOCK) return MG_IO_WAIT;
#endif
}
return n == 0 ? -1 : n < 0 && mg_sock_would_block() ? 0 : n;
if (n < 0 && mg_sock_would_block()) return MG_IO_WAIT;
if (n < 0 && mg_sock_conn_reset()) return MG_IO_RESET;
if (n <= 0) return MG_IO_ERR;
return n;
}
bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
if (c->is_udp) {
long n = mg_sock_send(c, buf, len);
long n = mg_io_send(c, buf, len);
MG_DEBUG(("%lu %p %d:%d %ld err %d", c->id, c->fd, (int) c->send.len,
(int) c->recv.len, n, MG_SOCK_ERRNO));
iolog(c, (char *) buf, n, false);
@@ -270,7 +271,7 @@ bool mg_open_listener(struct mg_connection *c, const char *url) {
return success;
}
static long mg_sock_recv(struct mg_connection *c, void *buf, size_t len) {
long mg_io_recv(struct mg_connection *c, void *buf, size_t len) {
long n = 0;
if (c->is_udp) {
union usa usa;
@@ -280,7 +281,10 @@ static long mg_sock_recv(struct mg_connection *c, void *buf, size_t len) {
} else {
n = recv(FD(c), (char *) buf, len, MSG_NONBLOCKING);
}
return n == 0 ? -1 : n < 0 && mg_sock_would_block() ? 0 : n;
if (n < 0 && mg_sock_would_block()) return MG_IO_WAIT;
if (n < 0 && mg_sock_conn_reset()) return MG_IO_RESET;
if (n <= 0) return MG_IO_ERR;
return n;
}
// NOTE(lsm): do only one iteration of reads, cause some systems
@@ -295,7 +299,7 @@ static void read_conn(struct mg_connection *c) {
} else {
char *buf = (char *) &c->recv.buf[c->recv.len];
size_t len = c->recv.size - c->recv.len;
n = c->is_tls ? mg_tls_recv(c, buf, len) : mg_sock_recv(c, buf, len);
n = c->is_tls ? mg_tls_recv(c, buf, len) : mg_io_recv(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_ERRNO));
@@ -306,7 +310,7 @@ static void read_conn(struct mg_connection *c) {
static void write_conn(struct mg_connection *c) {
char *buf = (char *) c->send.buf;
size_t len = c->send.len;
long n = c->is_tls ? mg_tls_send(c, buf, len) : mg_sock_send(c, buf, len);
long n = c->is_tls ? mg_tls_send(c, buf, len) : mg_io_send(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_ERRNO));
@@ -358,12 +362,10 @@ static void setsockopts(struct mg_connection *c) {
}
void mg_connect_resolved(struct mg_connection *c) {
// char buf[40];
int type = c->is_udp ? SOCK_DGRAM : SOCK_STREAM;
int rc, af = c->rem.is_ip6 ? AF_INET6 : AF_INET;
// mg_straddr(&c->rem, buf, sizeof(buf));
c->fd = S2PTR(socket(af, type, 0));
c->is_resolving = 0;
int rc, af = c->rem.is_ip6 ? AF_INET6 : AF_INET; // c->rem has resolved IP
c->fd = S2PTR(socket(af, type, 0)); // Create outbound socket
c->is_resolving = 0; // Clear resolving flag
if (FD(c) == INVALID_SOCKET) {
mg_error(c, "socket(): %d", MG_SOCK_ERRNO);
} else if (c->is_udp) {
+20 -34
View File
@@ -24,46 +24,27 @@ void mg_tls_free(struct mg_connection *c) {
}
}
bool mg_sock_would_block(void);
bool mg_sock_conn_reset(void);
#if MG_ENABLE_MIP
#else
static int mg_net_send(void *ctx, const unsigned char *buf, size_t len) {
struct mg_connection *c = (struct mg_connection *) ctx;
int fd = (int) (size_t) c->fd;
int n = (int) send(fd, buf, len, 0);
MG_VERBOSE(("%lu n=%d, errno=%d", c->id, n, errno));
if (n < 0) {
if (mg_sock_would_block()) return MBEDTLS_ERR_SSL_WANT_WRITE;
if (mg_sock_conn_reset()) return MBEDTLS_ERR_NET_CONN_RESET;
return MBEDTLS_ERR_NET_SEND_FAILED;
}
return n;
long n = mg_io_send((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_ERR) return MBEDTLS_ERR_NET_SEND_FAILED;
return (int) n;
}
static int mg_net_recv(void *ctx, unsigned char *buf, size_t len) {
struct mg_connection *c = (struct mg_connection *) ctx;
int n, fd = (int) (size_t) c->fd;
n = (int) recv(fd, buf, len, 0);
MG_VERBOSE(("%lu n=%d, errno=%d", c->id, n, errno));
if (n < 0) {
if (mg_sock_would_block()) return MBEDTLS_ERR_SSL_WANT_READ;
if (mg_sock_conn_reset()) return MBEDTLS_ERR_NET_CONN_RESET;
return MBEDTLS_ERR_NET_RECV_FAILED;
}
return n;
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_ERR) return MBEDTLS_ERR_NET_RECV_FAILED;
return (int) n;
}
#endif
void mg_tls_handshake(struct mg_connection *c) {
struct mg_tls *tls = (struct mg_tls *) c->tls;
int rc;
#if MG_ENABLE_MIP
#else
mbedtls_ssl_set_bio(&tls->ssl, c, mg_net_send, mg_net_recv, 0);
#endif
rc = mbedtls_ssl_handshake(&tls->ssl);
int rc = mbedtls_ssl_handshake(&tls->ssl);
if (rc == 0) { // Success
MG_DEBUG(("%lu success", c->id));
c->is_tls_hs = 0;
@@ -187,6 +168,7 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) {
c->tls = tls;
c->is_tls = 1;
c->is_tls_hs = 1;
mbedtls_ssl_set_bio(&tls->ssl, c, mg_net_send, mg_net_recv, 0);
if (c->is_client && c->is_resolving == 0 && c->is_connecting == 0) {
mg_tls_handshake(c);
}
@@ -203,12 +185,16 @@ size_t mg_tls_pending(struct mg_connection *c) {
long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
struct mg_tls *tls = (struct mg_tls *) c->tls;
long n = mbedtls_ssl_read(&tls->ssl, (unsigned char *) buf, len);
return n == 0 ? -1 : n == MBEDTLS_ERR_SSL_WANT_READ ? 0 : n;
if (n == MBEDTLS_ERR_SSL_WANT_READ) return MG_IO_WAIT;
if (n <= 0) return MG_IO_ERR;
return n;
}
long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
struct mg_tls *tls = (struct mg_tls *) c->tls;
long n = mbedtls_ssl_write(&tls->ssl, (unsigned char *) buf, len);
return n == 0 ? -1 : n == MBEDTLS_ERR_SSL_WANT_WRITE ? 0 : n;
if (n == MBEDTLS_ERR_SSL_WANT_WRITE) return MG_IO_WAIT;
if (n <= 0) return MG_IO_ERR;
return n;
}
#endif
+6 -2
View File
@@ -139,12 +139,16 @@ size_t mg_tls_pending(struct mg_connection *c) {
long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
struct mg_tls *tls = (struct mg_tls *) c->tls;
int n = SSL_read(tls->ssl, buf, (int) len);
return n == 0 ? -1 : n < 0 && mg_tls_err(tls, n) == 0 ? 0 : n;
if (n < 0 && mg_tls_err(tls, n) == 0) return MG_IO_WAIT;
if (n <= 0) return MG_IO_ERR;
return n;
}
long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
struct mg_tls *tls = (struct mg_tls *) c->tls;
int n = SSL_write(tls->ssl, buf, (int) len);
return n == 0 ? -1 : n < 0 && mg_tls_err(tls, n) == 0 ? 0 : n;
if (n < 0 && mg_tls_err(tls, n) == 0) return MG_IO_WAIT;
if (n <= 0) return MG_IO_ERR;
return n;
}
#endif