net: tcp: Avoid new packets from causing killing the pending send_timer
When there was no room to transmit the a next packet to be transmitted, the -ENOBUFS could cause the retransmission to fail. Secondly the conn->unacked_len can be set to 0 in the retransmission process, causing the subscribtion to the transmit timer to fail. Use the variable send_data_total instead. Make sure that is the send_data buffer becomes empty the send_timer is cancelled, but make sure any pending data still keeps on being transmitted. Signed-off-by: Sjors Hettinga <s.a.hettinga@gmail.com>
This commit is contained in:
parent
d74bd3d7d1
commit
0a9b2ed391
1 changed files with 13 additions and 9 deletions
|
@ -1107,7 +1107,7 @@ static int tcp_send_queued_data(struct tcp *conn)
|
||||||
(void)k_sem_take(&conn->tx_sem, K_NO_WAIT);
|
(void)k_sem_take(&conn->tx_sem, K_NO_WAIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn->unacked_len) {
|
if (conn->send_data_total) {
|
||||||
subscribe = true;
|
subscribe = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1115,14 +1115,6 @@ static int tcp_send_queued_data(struct tcp *conn)
|
||||||
subscribe = false;
|
subscribe = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we have out-of-bufs case, then do not start retransmit timer
|
|
||||||
* yet. The socket layer will catch this and resend data if needed.
|
|
||||||
*/
|
|
||||||
if (ret == -ENOBUFS) {
|
|
||||||
NET_DBG("No bufs, cancelling retransmit timer");
|
|
||||||
k_work_cancel_delayable(&conn->send_data_timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subscribe) {
|
if (subscribe) {
|
||||||
conn->send_data_retries = 0;
|
conn->send_data_retries = 0;
|
||||||
k_work_reschedule_for_queue(&tcp_work_q, &conn->send_data_timer,
|
k_work_reschedule_for_queue(&tcp_work_q, &conn->send_data_timer,
|
||||||
|
@ -2370,6 +2362,18 @@ int net_tcp_queue_data(struct net_context *context, struct net_pkt *pkt)
|
||||||
pkt->buffer = conn->send_data->buffer;
|
pkt->buffer = conn->send_data->buffer;
|
||||||
conn->send_data->buffer = NULL;
|
conn->send_data->buffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we have out-of-bufs case, and the send_data buffer has
|
||||||
|
* become empty, till the retransmit timer, as there is no
|
||||||
|
* data to retransmit.
|
||||||
|
* The socket layer will catch this and resend data if needed.
|
||||||
|
* Only perform this when it is just the newly added packet,
|
||||||
|
* otherwise it can disrupt any pending transmission
|
||||||
|
*/
|
||||||
|
if (conn->send_data_total == 0) {
|
||||||
|
NET_DBG("No bufs, cancelling retransmit timer");
|
||||||
|
k_work_cancel_delayable(&conn->send_data_timer);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* We should not free the pkt if there was an error. It will be
|
/* We should not free the pkt if there was an error. It will be
|
||||||
* freed in net_context.c:context_sendto()
|
* freed in net_context.c:context_sendto()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue