Commit b2e2ad9a authored by Deomid Ryabkov's avatar Deomid Ryabkov Committed by Cesanta Bot

Fix hexdump on ESP8266, deliver MG_EV_SEND [...]

[...] after handing data off to LWIP, do not wait for ACK.
We don't do it in net_if_socket, don't do it here either.
Also prevents multiple send attempt on the same send_mbuf data.

PUBLISHED_FROM=4e5a677ebda84af1514f34299e53ce856a537883
parent a07fb2be
...@@ -2020,12 +2020,10 @@ MG_INTERNAL void mg_call(struct mg_connection *nc, ...@@ -2020,12 +2020,10 @@ MG_INTERNAL void mg_call(struct mg_connection *nc,
} }
#if !defined(NO_LIBC) && MG_ENABLE_HEXDUMP #if !defined(NO_LIBC) && MG_ENABLE_HEXDUMP
/* LCOV_EXCL_START */
if (nc->mgr->hexdump_file != NULL && ev != MG_EV_POLL && ev != MG_EV_RECV && if (nc->mgr->hexdump_file != NULL && ev != MG_EV_POLL && ev != MG_EV_RECV &&
ev != MG_EV_SEND /* handled separately */) { ev != MG_EV_SEND /* handled separately */) {
mg_hexdump_connection(nc, nc->mgr->hexdump_file, NULL, 0, ev); mg_hexdump_connection(nc, nc->mgr->hexdump_file, NULL, 0, ev);
} }
/* LCOV_EXCL_STOP */
#endif #endif
if (ev_handler != NULL) { if (ev_handler != NULL) {
unsigned long flags_before = nc->flags; unsigned long flags_before = nc->flags;
...@@ -9591,8 +9589,7 @@ void mg_hexdumpf(FILE *fp, const void *buf, int len) { ...@@ -9591,8 +9589,7 @@ void mg_hexdumpf(FILE *fp, const void *buf, int len) {
void mg_hexdump_connection(struct mg_connection *nc, const char *path, void mg_hexdump_connection(struct mg_connection *nc, const char *path,
const void *buf, int num_bytes, int ev) { const void *buf, int num_bytes, int ev) {
FILE *fp = NULL; FILE *fp = NULL;
char *hexbuf, src[60], dst[60]; char src[60], dst[60];
int buf_size = num_bytes * 5 + 100;
const char *tag = NULL; const char *tag = NULL;
switch (ev) { switch (ev) {
case MG_EV_RECV: case MG_EV_RECV:
...@@ -9630,13 +9627,11 @@ void mg_hexdump_connection(struct mg_connection *nc, const char *path, ...@@ -9630,13 +9627,11 @@ void mg_hexdump_connection(struct mg_connection *nc, const char *path,
MG_SOCK_STRINGIFY_PORT | MG_SOCK_STRINGIFY_PORT |
MG_SOCK_STRINGIFY_REMOTE); MG_SOCK_STRINGIFY_REMOTE);
fprintf(fp, "%lu %p %s %s %s %d\n", (unsigned long) mg_time(), (void *) nc, fprintf(fp, "%lu %p %s %s %s %d\n", (unsigned long) mg_time(), (void *) nc,
src, tag, dst, num_bytes); src, tag, dst, (int) num_bytes);
if (num_bytes > 0 && (hexbuf = (char *) MG_MALLOC(buf_size)) != NULL) { if (num_bytes > 0) {
mg_hexdump(buf, num_bytes, hexbuf, buf_size); mg_hexdumpf(fp, buf, num_bytes);
fprintf(fp, "%s", hexbuf);
MG_FREE(hexbuf);
} }
if (fp != stdin && fp != stdout) fclose(fp); if (fp != stdout && fp != stderr) fclose(fp);
} }
#endif #endif
...@@ -13983,10 +13978,9 @@ struct mg_lwip_conn_state { ...@@ -13983,10 +13978,9 @@ struct mg_lwip_conn_state {
enum mg_sig_type { enum mg_sig_type {
MG_SIG_CONNECT_RESULT = 1, MG_SIG_CONNECT_RESULT = 1,
MG_SIG_RECV = 2, MG_SIG_RECV = 2,
MG_SIG_SENT_CB = 3, MG_SIG_CLOSE_CONN = 3,
MG_SIG_CLOSE_CONN = 4, MG_SIG_TOMBSTONE = 4,
MG_SIG_TOMBSTONE = 5, MG_SIG_ACCEPT = 5,
MG_SIG_ACCEPT = 6,
}; };
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);
...@@ -14206,14 +14200,10 @@ static err_t mg_lwip_tcp_sent_cb(void *arg, struct tcp_pcb *tpcb, ...@@ -14206,14 +14200,10 @@ static err_t mg_lwip_tcp_sent_cb(void *arg, struct tcp_pcb *tpcb,
u16_t num_sent) { u16_t num_sent) {
struct mg_connection *nc = (struct mg_connection *) arg; struct mg_connection *nc = (struct mg_connection *) arg;
DBG(("%p %p %u", nc, tpcb, num_sent)); DBG(("%p %p %u", nc, tpcb, num_sent));
if (nc == NULL) { if ((nc->flags & MG_F_SEND_AND_CLOSE) && !(nc->flags & MG_F_WANT_WRITE) &&
tcp_abort(tpcb); nc->send_mbuf.len == 0 && tpcb->unacked == 0) {
return ERR_ABRT; mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);
} }
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
cs->num_sent += num_sent;
mg_lwip_post_signal(MG_SIG_SENT_CB, nc);
return ERR_OK; return ERR_OK;
} }
...@@ -14436,49 +14426,29 @@ int mg_lwip_tcp_write(struct mg_connection *nc, const void *data, ...@@ -14436,49 +14426,29 @@ int mg_lwip_tcp_write(struct mg_connection *nc, const void *data,
len = MIN(len, (TCP_MSS - tpcb->unsent->len)); len = MIN(len, (TCP_MSS - tpcb->unsent->len));
} }
#endif #endif
err_t err = tcp_write(tpcb, data, len, TCP_WRITE_FLAG_COPY); cs->err = tcp_write(tpcb, data, len, TCP_WRITE_FLAG_COPY);
DBG(("%p tcp_write %u = %d", tpcb, len, err)); DBG(("%p tcp_write %u = %d", tpcb, len, cs->err));
if (err != ERR_OK) { if (cs->err != ERR_OK) {
/* /*
* We ignore ERR_MEM because memory will be freed up when the data is sent * We ignore ERR_MEM because memory will be freed up when the data is sent
* and we'll retry. * and we'll retry.
*/ */
return (err == ERR_MEM ? 0 : -1); return (cs->err == ERR_MEM ? 0 : -1);
} }
return len; return len;
} }
static void mg_lwip_send_more(struct mg_connection *nc) { static int mg_lwip_udp_send(struct mg_connection *nc, const void *data,
uint16_t len) {
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;
if (nc->sock == INVALID_SOCKET || cs->pcb.tcp == NULL) { if (cs->pcb.udp == NULL) {
DBG(("%p invalid socket", nc));
return;
}
int num_written = mg_lwip_tcp_write(nc, nc->send_mbuf.buf, nc->send_mbuf.len);
DBG(("%p mg_lwip_tcp_write %u = %d", nc, nc->send_mbuf.len, num_written));
if (num_written == 0) return;
if (num_written < 0) {
mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);
}
}
void mg_lwip_if_tcp_send(struct mg_connection *nc, const void *buf,
size_t len) {
mbuf_append(&nc->send_mbuf, buf, len);
mg_lwip_mgr_schedule_poll(nc->mgr);
}
void mg_lwip_if_udp_send(struct mg_connection *nc, const void *buf,
size_t len) {
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
if (nc->sock == INVALID_SOCKET || cs->pcb.udp == NULL) {
/* /*
* In case of UDP, this usually means, what * In case of UDP, this usually means, what
* async DNS resolve is still in progress and connection * async DNS resolve is still in progress and connection
* is not ready yet * is not ready yet
*/ */
DBG(("%p socket is not connected", nc)); DBG(("%p socket is not connected", nc));
return; return -1;
} }
struct udp_pcb *upcb = cs->pcb.udp; struct udp_pcb *upcb = cs->pcb.udp;
struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
...@@ -14486,20 +14456,45 @@ void mg_lwip_if_udp_send(struct mg_connection *nc, const void *buf, ...@@ -14486,20 +14456,45 @@ void mg_lwip_if_udp_send(struct mg_connection *nc, const void *buf,
u16_t port = ntohs(nc->sa.sin.sin_port); u16_t port = ntohs(nc->sa.sin.sin_port);
if (p == NULL) { if (p == NULL) {
DBG(("OOM")); DBG(("OOM"));
return; return 0;
} }
memcpy(p->payload, buf, len); memcpy(p->payload, data, len);
cs->err = udp_sendto(upcb, p, (ip_addr_t *) ip, port); cs->err = udp_sendto(upcb, p, (ip_addr_t *) ip, port);
DBG(("%p udp_sendto = %d", nc, cs->err)); DBG(("%p udp_sendto = %d", nc, cs->err));
pbuf_free(p); pbuf_free(p);
if (cs->err != ERR_OK) { return (cs->err == ERR_OK ? len : -1);
mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc); }
static void mg_lwip_send_more(struct mg_connection *nc) {
int num_sent = 0;
if (nc->sock == INVALID_SOCKET) return;
if (nc->flags & MG_F_UDP) {
num_sent = mg_lwip_udp_send(nc, nc->send_mbuf.buf, nc->send_mbuf.len);
DBG(("%p mg_lwip_udp_send %u = %d", nc, nc->send_mbuf.len, num_sent));
} else {
num_sent = mg_lwip_tcp_write(nc, nc->send_mbuf.buf, nc->send_mbuf.len);
DBG(("%p mg_lwip_tcp_write %u = %d", nc, nc->send_mbuf.len, num_sent));
}
if (num_sent == 0) return;
if (num_sent > 0) {
mg_if_sent_cb(nc, num_sent);
} else { } else {
cs->num_sent += len; mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);
mg_lwip_post_signal(MG_SIG_SENT_CB, nc);
} }
} }
void mg_lwip_if_tcp_send(struct mg_connection *nc, const void *buf,
size_t len) {
mbuf_append(&nc->send_mbuf, buf, len);
mg_lwip_mgr_schedule_poll(nc->mgr);
}
void mg_lwip_if_udp_send(struct mg_connection *nc, const void *buf,
size_t len) {
mbuf_append(&nc->send_mbuf, buf, len);
mg_lwip_mgr_schedule_poll(nc->mgr);
}
void mg_lwip_if_recved(struct mg_connection *nc, size_t len) { void mg_lwip_if_recved(struct mg_connection *nc, size_t len) {
if (nc->flags & MG_F_UDP) return; if (nc->flags & MG_F_UDP) return;
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;
...@@ -14697,17 +14692,6 @@ void mg_ev_mgr_lwip_process_signals(struct mg_mgr *mgr) { ...@@ -14697,17 +14692,6 @@ void mg_ev_mgr_lwip_process_signals(struct mg_mgr *mgr) {
} }
break; break;
} }
case MG_SIG_SENT_CB: {
mg_if_sent_cb(nc, cs->num_sent);
cs->num_sent = 0;
if (nc->send_mbuf.len == 0 && (nc->flags & MG_F_SEND_AND_CLOSE) &&
!(nc->flags & MG_F_WANT_WRITE)) {
mg_close_conn(nc);
}
break;
}
case MG_SIG_TOMBSTONE: { case MG_SIG_TOMBSTONE: {
break; break;
} }
...@@ -14791,8 +14775,8 @@ time_t mg_lwip_if_poll(struct mg_iface *iface, int timeout_ms) { ...@@ -14791,8 +14775,8 @@ time_t mg_lwip_if_poll(struct mg_iface *iface, int timeout_ms) {
} else } else
#endif /* MG_ENABLE_SSL */ #endif /* MG_ENABLE_SSL */
{ {
if (!(nc->flags & (MG_F_CONNECTING | MG_F_UDP))) { if (nc->send_mbuf.len > 0 && !(nc->flags & MG_F_CONNECTING)) {
if (nc->send_mbuf.len > 0) mg_lwip_send_more(nc); mg_lwip_send_more(nc);
} }
} }
if (nc->sock != INVALID_SOCKET && if (nc->sock != INVALID_SOCKET &&
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment