diff --git a/mongoose.c b/mongoose.c index 2f0db086..83bea6b0 100644 --- a/mongoose.c +++ b/mongoose.c @@ -4407,12 +4407,13 @@ static struct ip *tx_ip(struct mg_tcpip_if *ifp, uint8_t *mac_dst, return ip; } -static void tx_udp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src, +static bool tx_udp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src, uint16_t sport, uint32_t ip_dst, uint16_t dport, const void *buf, size_t len) { struct ip *ip = tx_ip(ifp, mac_dst, 17, ip_src, ip_dst, len + sizeof(struct udp)); struct udp *udp = (struct udp *) (ip + 1); + size_t eth_len; // MG_DEBUG(("UDP XX LEN %d %d", (int) len, (int) ifp->tx.len)); udp->sport = sport; udp->dport = dport; @@ -4426,7 +4427,8 @@ static void tx_udp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src, udp->csum = csumfin(cs); memmove(udp + 1, buf, len); // MG_DEBUG(("UDP LEN %d %d", (int) len, (int) ifp->frame_len)); - ether_output(ifp, sizeof(struct eth) + sizeof(*ip) + sizeof(*udp) + len); + eth_len = sizeof(struct eth) + sizeof(*ip) + sizeof(*udp) + len; + return (ether_output(ifp, eth_len) == eth_len); } static void tx_dhcp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src, @@ -4801,7 +4803,9 @@ long mg_io_send(struct mg_connection *c, const void *buf, size_t len) { uint32_t dst_ip = *(uint32_t *) c->rem.ip; len = trim_len(c, len); if (c->is_udp) { - tx_udp(ifp, s->mac, ifp->ip, c->loc.port, dst_ip, c->rem.port, buf, len); + if (!tx_udp(ifp, s->mac, ifp->ip, c->loc.port, dst_ip, c->rem.port, buf, + len)) + return MG_IO_WAIT; } else { // TCP, cap to peer's MSS size_t sent; if (len > s->dmss) len = s->dmss; // RFC-6691: reduce if sending opts @@ -5421,8 +5425,8 @@ bool mg_send(struct mg_connection *c, const void *buf, size_t len) { } else if (c->is_udp) { struct connstate *s = (struct connstate *) (c + 1); len = trim_len(c, len); // Trimming length if necessary - tx_udp(ifp, s->mac, ifp->ip, c->loc.port, rem_ip, c->rem.port, buf, len); - res = true; + res = tx_udp(ifp, s->mac, ifp->ip, c->loc.port, rem_ip, c->rem.port, buf, + len); } else { res = mg_iobuf_add(&c->send, c->send.len, buf, len); } diff --git a/src/net_builtin.c b/src/net_builtin.c index c840d5f9..461a37df 100644 --- a/src/net_builtin.c +++ b/src/net_builtin.c @@ -241,12 +241,13 @@ static struct ip *tx_ip(struct mg_tcpip_if *ifp, uint8_t *mac_dst, return ip; } -static void tx_udp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src, +static bool tx_udp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src, uint16_t sport, uint32_t ip_dst, uint16_t dport, const void *buf, size_t len) { struct ip *ip = tx_ip(ifp, mac_dst, 17, ip_src, ip_dst, len + sizeof(struct udp)); struct udp *udp = (struct udp *) (ip + 1); + size_t eth_len; // MG_DEBUG(("UDP XX LEN %d %d", (int) len, (int) ifp->tx.len)); udp->sport = sport; udp->dport = dport; @@ -260,7 +261,8 @@ static void tx_udp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src, udp->csum = csumfin(cs); memmove(udp + 1, buf, len); // MG_DEBUG(("UDP LEN %d %d", (int) len, (int) ifp->frame_len)); - ether_output(ifp, sizeof(struct eth) + sizeof(*ip) + sizeof(*udp) + len); + eth_len = sizeof(struct eth) + sizeof(*ip) + sizeof(*udp) + len; + return (ether_output(ifp, eth_len) == eth_len); } static void tx_dhcp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src, @@ -635,7 +637,9 @@ long mg_io_send(struct mg_connection *c, const void *buf, size_t len) { uint32_t dst_ip = *(uint32_t *) c->rem.ip; len = trim_len(c, len); if (c->is_udp) { - tx_udp(ifp, s->mac, ifp->ip, c->loc.port, dst_ip, c->rem.port, buf, len); + if (!tx_udp(ifp, s->mac, ifp->ip, c->loc.port, dst_ip, c->rem.port, buf, + len)) + return MG_IO_WAIT; } else { // TCP, cap to peer's MSS size_t sent; if (len > s->dmss) len = s->dmss; // RFC-6691: reduce if sending opts @@ -1255,8 +1259,8 @@ bool mg_send(struct mg_connection *c, const void *buf, size_t len) { } else if (c->is_udp) { struct connstate *s = (struct connstate *) (c + 1); len = trim_len(c, len); // Trimming length if necessary - tx_udp(ifp, s->mac, ifp->ip, c->loc.port, rem_ip, c->rem.port, buf, len); - res = true; + res = tx_udp(ifp, s->mac, ifp->ip, c->loc.port, rem_ip, c->rem.port, buf, + len); } else { res = mg_iobuf_add(&c->send, c->send.len, buf, len); }