mirror of
https://github.com/cesanta/mongoose.git
synced 2025-01-19 08:03:14 +08:00
Do not double-count recved bytes
Mongoose would report consumed bytes twice if mg_call is invoked recursively (e.g. proto_handler uses mg_call to invoke user's handler). Reporting twice as much recved as was delivered effectively disables LwIP's TCP throttling and causes buffers to grow too big. PUBLISHED_FROM=4ad5cd5db4dd54623bd6de2d50d32ddcc9e2b08a
This commit is contained in:
parent
8065439f96
commit
1db747da29
13
mongoose.c
13
mongoose.c
@ -2218,6 +2218,8 @@ MG_INTERNAL void mg_remove_conn(struct mg_connection *conn) {
|
|||||||
MG_INTERNAL void mg_call(struct mg_connection *nc,
|
MG_INTERNAL void mg_call(struct mg_connection *nc,
|
||||||
mg_event_handler_t ev_handler, void *user_data, int ev,
|
mg_event_handler_t ev_handler, void *user_data, int ev,
|
||||||
void *ev_data) {
|
void *ev_data) {
|
||||||
|
static int nesting_level = 0;
|
||||||
|
nesting_level++;
|
||||||
if (ev_handler == NULL) {
|
if (ev_handler == NULL) {
|
||||||
/*
|
/*
|
||||||
* If protocol handler is specified, call it. Otherwise, call user-specified
|
* If protocol handler is specified, call it. Otherwise, call user-specified
|
||||||
@ -2247,7 +2249,10 @@ MG_INTERNAL void mg_call(struct mg_connection *nc,
|
|||||||
nc->flags = (flags_before & ~_MG_CALLBACK_MODIFIABLE_FLAGS_MASK) |
|
nc->flags = (flags_before & ~_MG_CALLBACK_MODIFIABLE_FLAGS_MASK) |
|
||||||
(nc->flags & _MG_CALLBACK_MODIFIABLE_FLAGS_MASK);
|
(nc->flags & _MG_CALLBACK_MODIFIABLE_FLAGS_MASK);
|
||||||
}
|
}
|
||||||
if (recved > 0 && !(nc->flags & MG_F_UDP)) {
|
/* It's important to not double-count recved bytes, and since mg_call can be
|
||||||
|
* called recursively (e.g. proto_handler invokes user handler), we keep
|
||||||
|
* track of recursion and only report received bytes at the top level. */
|
||||||
|
if (nesting_level == 1 && recved > 0 && !(nc->flags & MG_F_UDP)) {
|
||||||
nc->iface->vtable->recved(nc, recved);
|
nc->iface->vtable->recved(nc, recved);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2256,6 +2261,7 @@ MG_INTERNAL void mg_call(struct mg_connection *nc,
|
|||||||
ev_handler == nc->handler ? "user" : "proto", nc->flags,
|
ev_handler == nc->handler ? "user" : "proto", nc->flags,
|
||||||
(int) nc->recv_mbuf.len, (int) nc->send_mbuf.len));
|
(int) nc->recv_mbuf.len, (int) nc->send_mbuf.len));
|
||||||
}
|
}
|
||||||
|
nesting_level--;
|
||||||
#if !MG_ENABLE_CALLBACK_USERDATA
|
#if !MG_ENABLE_CALLBACK_USERDATA
|
||||||
(void) user_data;
|
(void) user_data;
|
||||||
#endif
|
#endif
|
||||||
@ -14439,6 +14445,7 @@ static err_t mg_lwip_tcp_recv_cb(void *arg, struct tcp_pcb *tpcb,
|
|||||||
struct pbuf *q = p->next;
|
struct pbuf *q = p->next;
|
||||||
for (; q != NULL; q = q->next) pbuf_ref(q);
|
for (; q != NULL; q = q->next) pbuf_ref(q);
|
||||||
}
|
}
|
||||||
|
mgos_lock();
|
||||||
if (cs->rx_chain == NULL) {
|
if (cs->rx_chain == NULL) {
|
||||||
cs->rx_offset = 0;
|
cs->rx_offset = 0;
|
||||||
} else if (pbuf_clen(cs->rx_chain) >= 4) {
|
} else if (pbuf_clen(cs->rx_chain) >= 4) {
|
||||||
@ -14452,6 +14459,7 @@ static err_t mg_lwip_tcp_recv_cb(void *arg, struct tcp_pcb *tpcb,
|
|||||||
p = np;
|
p = np;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mgos_unlock();
|
||||||
mg_lwip_recv_common(nc, p);
|
mg_lwip_recv_common(nc, p);
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
@ -14929,7 +14937,8 @@ void mg_lwip_if_recved(struct mg_connection *nc, size_t len) {
|
|||||||
DBG(("%p invalid socket", nc));
|
DBG(("%p invalid socket", nc));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DBG(("%p %p %u", nc, cs->pcb.tcp, len));
|
DBG(("%p %p %u %u", nc, cs->pcb.tcp, len,
|
||||||
|
(cs->rx_chain ? cs->rx_chain->tot_len : 0)));
|
||||||
struct tcp_recved_ctx ctx = {.tpcb = cs->pcb.tcp, .len = len};
|
struct tcp_recved_ctx ctx = {.tpcb = cs->pcb.tcp, .len = len};
|
||||||
#if MG_ENABLE_SSL
|
#if MG_ENABLE_SSL
|
||||||
if (!(nc->flags & MG_F_SSL)) {
|
if (!(nc->flags & MG_F_SSL)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user