From dd4ded3978fe210160add304b21692c47e55c8f3 Mon Sep 17 00:00:00 2001 From: Joel Cunningham Date: Sat, 4 Mar 2017 12:29:43 -0600 Subject: [PATCH] do_writemore: fix blocking bug A bug was introduced in the atomic vector feature for blocking netconns where if we couldn't write the entire vector due to send buffer being full (write_more is 0), we would not update the vector state and then when sent_tcp() is called, it would actually re-send the previous vector and if additional calls were required to finish the write, msg.w.offset would eventually exceed msg.w.len, This was found by testing "stats" from the shell and hitting the LWIP_ASSERT in do_writemore() that checks offset < len The fix simply updates the vector state after every ERR_OK return from tcp_write(). While not all cases (non-blocking sockets) need to update the state in this case, it keeps the logic simple and also makes debugging simpler because you don't have stale vector state at any point --- src/api/api_msg.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/api/api_msg.c b/src/api/api_msg.c index 6a3fb3e3..dfecaf09 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -1560,17 +1560,14 @@ lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM) err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags); if (err == ERR_OK) { conn->current_msg->msg.w.offset += len; - /* update write state if making another loop */ - if (write_more) { - conn->current_msg->msg.w.vector_off += len; - /* check if current vector is finished */ - if (conn->current_msg->msg.w.vector_off == conn->current_msg->msg.w.vector->len) { - conn->current_msg->msg.w.vector_cnt--; - /* if we have additional vectors, move on to them */ - if (conn->current_msg->msg.w.vector_cnt > 0) { - conn->current_msg->msg.w.vector++; - conn->current_msg->msg.w.vector_off = 0; - } + conn->current_msg->msg.w.vector_off += len; + /* check if current vector is finished */ + if (conn->current_msg->msg.w.vector_off == conn->current_msg->msg.w.vector->len) { + conn->current_msg->msg.w.vector_cnt--; + /* if we have additional vectors, move on to them */ + if (conn->current_msg->msg.w.vector_cnt > 0) { + conn->current_msg->msg.w.vector++; + conn->current_msg->msg.w.vector_off = 0; } } }