mirror of
https://github.com/cesanta/mongoose.git
synced 2025-06-11 03:46:25 +08:00
Krypton + LWIP fixes
* Make kr_{send,recv} report status via return code instaed of errno * Move mg_if_* recv and connect callback invocation out of LWIP callbacks: these can be nested and we don't want that to happen to our callbacks. Instead, we post events for the event manager to process during next poll. PUBLISHED_FROM=9b3c1de796fae381dea1641807e51d7a897a398e
This commit is contained in:
parent
e3bac87016
commit
204bf9acec
68
mongoose.c
68
mongoose.c
@ -11339,10 +11339,11 @@ struct mg_lwip_conn_state {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum mg_sig_type {
|
enum mg_sig_type {
|
||||||
MG_SIG_CONNECT_RESULT = 1, /* struct mg_connection* */
|
MG_SIG_CONNECT_RESULT = 1,
|
||||||
MG_SIG_SENT_CB = 2, /* struct mg_connection* */
|
MG_SIG_RECV = 2,
|
||||||
MG_SIG_CLOSE_CONN = 3, /* struct mg_connection* */
|
MG_SIG_SENT_CB = 3,
|
||||||
MG_SIG_TOMBSTONE = 4,
|
MG_SIG_CLOSE_CONN = 4,
|
||||||
|
MG_SIG_TOMBSTONE = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
void mg_lwip_post_signal(enum mg_sig_type sig, struct mg_connection *nc);
|
void mg_lwip_post_signal(enum mg_sig_type sig, struct mg_connection *nc);
|
||||||
@ -11437,15 +11438,7 @@ static err_t mg_lwip_tcp_conn_cb(void *arg, struct tcp_pcb *tpcb, err_t err) {
|
|||||||
#if LWIP_TCP_KEEPALIVE
|
#if LWIP_TCP_KEEPALIVE
|
||||||
if (err == 0) mg_lwip_set_keepalive_params(nc, 60, 10, 6);
|
if (err == 0) mg_lwip_set_keepalive_params(nc, 60, 10, 6);
|
||||||
#endif
|
#endif
|
||||||
#ifdef SSL_KRYPTON
|
mg_lwip_post_signal(MG_SIG_CONNECT_RESULT, nc);
|
||||||
if (err == 0 && nc->ssl != NULL) {
|
|
||||||
SSL_set_fd(nc->ssl, (intptr_t) nc);
|
|
||||||
mg_lwip_ssl_do_hs(nc);
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
mg_lwip_post_signal(MG_SIG_CONNECT_RESULT, nc);
|
|
||||||
}
|
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11504,6 +11497,12 @@ static err_t mg_lwip_tcp_recv_cb(void *arg, struct tcp_pcb *tpcb,
|
|||||||
}
|
}
|
||||||
pbuf_chain(cs->rx_chain, p);
|
pbuf_chain(cs->rx_chain, p);
|
||||||
}
|
}
|
||||||
|
mg_lwip_post_signal(MG_SIG_RECV, nc);
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mg_lwip_handle_recv(struct mg_connection *nc) {
|
||||||
|
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
|
||||||
|
|
||||||
#ifdef SSL_KRYPTON
|
#ifdef SSL_KRYPTON
|
||||||
if (nc->ssl != NULL) {
|
if (nc->ssl != NULL) {
|
||||||
@ -11512,7 +11511,7 @@ static err_t mg_lwip_tcp_recv_cb(void *arg, struct tcp_pcb *tpcb,
|
|||||||
} else {
|
} else {
|
||||||
mg_lwip_ssl_do_hs(nc);
|
mg_lwip_ssl_do_hs(nc);
|
||||||
}
|
}
|
||||||
return ERR_OK;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -11522,7 +11521,7 @@ static err_t mg_lwip_tcp_recv_cb(void *arg, struct tcp_pcb *tpcb,
|
|||||||
char *data = (char *) malloc(len);
|
char *data = (char *) malloc(len);
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
DBG(("OOM"));
|
DBG(("OOM"));
|
||||||
return ERR_MEM;
|
return;
|
||||||
}
|
}
|
||||||
pbuf_copy_partial(seg, data, len, cs->rx_offset);
|
pbuf_copy_partial(seg, data, len, cs->rx_offset);
|
||||||
mg_if_recv_tcp_cb(nc, data, len); /* callee takes over data */
|
mg_if_recv_tcp_cb(nc, data, len); /* callee takes over data */
|
||||||
@ -11537,7 +11536,6 @@ static err_t mg_lwip_tcp_recv_cb(void *arg, struct tcp_pcb *tpcb,
|
|||||||
if (nc->send_mbuf.len > 0) {
|
if (nc->send_mbuf.len > 0) {
|
||||||
mg_lwip_mgr_schedule_poll(nc->mgr);
|
mg_lwip_mgr_schedule_poll(nc->mgr);
|
||||||
}
|
}
|
||||||
return ERR_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static err_t mg_lwip_tcp_sent_cb(void *arg, struct tcp_pcb *tpcb,
|
static err_t mg_lwip_tcp_sent_cb(void *arg, struct tcp_pcb *tpcb,
|
||||||
@ -11892,7 +11890,15 @@ void mg_ev_mgr_lwip_process_signals(struct mg_mgr *mgr) {
|
|||||||
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
|
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
|
||||||
switch (md->sig_queue[md->start_index].sig) {
|
switch (md->sig_queue[md->start_index].sig) {
|
||||||
case MG_SIG_CONNECT_RESULT: {
|
case MG_SIG_CONNECT_RESULT: {
|
||||||
mg_if_connect_cb(nc, cs->err);
|
#ifdef SSL_KRYPTON
|
||||||
|
if (cs->err == 0 && nc->flags & MG_F_SSL && !(nc->flags & MG_F_SSL_HANDSHAKE_DONE)) {
|
||||||
|
SSL_set_fd(nc->ssl, (intptr_t) nc);
|
||||||
|
mg_lwip_ssl_do_hs(nc);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
mg_if_connect_cb(nc, cs->err);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MG_SIG_CLOSE_CONN: {
|
case MG_SIG_CLOSE_CONN: {
|
||||||
@ -11900,6 +11906,10 @@ void mg_ev_mgr_lwip_process_signals(struct mg_mgr *mgr) {
|
|||||||
mg_close_conn(nc);
|
mg_close_conn(nc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MG_SIG_RECV: {
|
||||||
|
mg_lwip_handle_recv(nc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case MG_SIG_SENT_CB: {
|
case MG_SIG_SENT_CB: {
|
||||||
if (cs->num_sent > 0) mg_if_sent_cb(nc, cs->num_sent);
|
if (cs->num_sent > 0) mg_if_sent_cb(nc, cs->num_sent);
|
||||||
cs->num_sent = 0;
|
cs->num_sent = 0;
|
||||||
@ -11945,7 +11955,9 @@ time_t mg_mgr_poll(struct mg_mgr *mgr, int timeout_ms) {
|
|||||||
struct mg_connection *nc, *tmp;
|
struct mg_connection *nc, *tmp;
|
||||||
double min_timer = 0;
|
double min_timer = 0;
|
||||||
int num_timers = 0;
|
int num_timers = 0;
|
||||||
|
#if 0
|
||||||
DBG(("begin poll @%u", (unsigned int) (now * 1000)));
|
DBG(("begin poll @%u", (unsigned int) (now * 1000)));
|
||||||
|
#endif
|
||||||
mg_ev_mgr_lwip_process_signals(mgr);
|
mg_ev_mgr_lwip_process_signals(mgr);
|
||||||
for (nc = mgr->active_connections; nc != NULL; nc = tmp) {
|
for (nc = mgr->active_connections; nc != NULL; nc = tmp) {
|
||||||
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
|
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
|
||||||
@ -11996,9 +12008,12 @@ time_t mg_mgr_poll(struct mg_mgr *mgr, int timeout_ms) {
|
|||||||
num_timers++;
|
num_timers++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
DBG(("end poll @%u, %d conns, %d timers (min %u), next in %d ms",
|
DBG(("end poll @%u, %d conns, %d timers (min %u), next in %d ms",
|
||||||
(unsigned int) (now * 1000), n, num_timers,
|
(unsigned int) (now * 1000), n, num_timers,
|
||||||
(unsigned int) (min_timer * 1000), timeout_ms));
|
(unsigned int) (min_timer * 1000), timeout_ms));
|
||||||
|
#endif
|
||||||
|
(void) timeout_ms;
|
||||||
return now;
|
return now;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -12147,8 +12162,11 @@ void mg_lwip_ssl_recv(struct mg_connection *nc) {
|
|||||||
cs->err = 0;
|
cs->err = 0;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
LOG(LL_ERROR, ("SSL read error: %d", err));
|
if (err != SSL_ERROR_ZERO_RETURN) {
|
||||||
|
LOG(LL_ERROR, ("SSL read error: %d", err));
|
||||||
|
}
|
||||||
mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);
|
mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mg_if_recv_tcp_cb(nc, buf, ret); /* callee takes over data */
|
mg_if_recv_tcp_cb(nc, buf, ret); /* callee takes over data */
|
||||||
@ -12161,27 +12179,21 @@ void mg_lwip_ssl_recv(struct mg_connection *nc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t kr_send(int fd, const void *buf, size_t len, int flags) {
|
ssize_t kr_send(int fd, const void *buf, size_t len) {
|
||||||
struct mg_connection *nc = (struct mg_connection *) fd;
|
struct mg_connection *nc = (struct mg_connection *) fd;
|
||||||
int ret = mg_lwip_tcp_write(nc, buf, len);
|
int ret = mg_lwip_tcp_write(nc, buf, len);
|
||||||
(void) flags;
|
|
||||||
DBG(("mg_lwip_tcp_write %u = %d", len, ret));
|
DBG(("mg_lwip_tcp_write %u = %d", len, ret));
|
||||||
if (ret <= 0) {
|
if (ret == 0) ret = KR_IO_WOULDBLOCK;
|
||||||
errno = (ret == 0 ? EWOULDBLOCK : EIO);
|
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t kr_recv(int fd, void *buf, size_t len, int flags) {
|
ssize_t kr_recv(int fd, void *buf, size_t len) {
|
||||||
struct mg_connection *nc = (struct mg_connection *) fd;
|
struct mg_connection *nc = (struct mg_connection *) fd;
|
||||||
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
|
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
|
||||||
struct pbuf *seg = cs->rx_chain;
|
struct pbuf *seg = cs->rx_chain;
|
||||||
(void) flags;
|
|
||||||
if (seg == NULL) {
|
if (seg == NULL) {
|
||||||
DBG(("%u - nothing to read", len));
|
DBG(("%u - nothing to read", len));
|
||||||
errno = EWOULDBLOCK;
|
return KR_IO_WOULDBLOCK;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
size_t seg_len = (seg->len - cs->rx_offset);
|
size_t seg_len = (seg->len - cs->rx_offset);
|
||||||
DBG(("%u %u %u %u", len, cs->rx_chain->len, seg_len, cs->rx_chain->tot_len));
|
DBG(("%u %u %u %u", len, cs->rx_chain->len, seg_len, cs->rx_chain->tot_len));
|
||||||
|
Loading…
Reference in New Issue
Block a user