mirror of
https://github.com/cesanta/mongoose.git
synced 2026-11-01 13:10:43 +00:00
Add mbedtls support to MIP
This commit is contained in:
1 parent
f76a7e36e8
commit
124ac12150
16 files changed
+446
-303
No files matched your search
@@ -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
@@ -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:
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
Reference in new issue
Block a user