net: tcp: Fix accidental removal of data from send_data

In the function net_tcp_queue_data. When an -ENOBUFS by
tcp_send_queued_data is returned, it throws away the whole block of size
len from the send_data. If the len is > MSS, it could happen that the
first section is transmitted, but at the second an -ENOBUFS occurs.
In that case the data is transmitted, but later on removed from the
send_data.

To circumvent this problem, check if the len + unacked_len is smaller
then the send_data_total. If so, the data can safely be removed from
send_data. Otherwise, just pretend the transmission went OK. The
acknowledgment and retransmit path will eventually take care of it.

Signed-off-by: Sjors Hettinga <s.a.hettinga@gmail.com>
This commit is contained in:
Sjors Hettinga 2022-06-07 07:58:11 +02:00 committed by Carles Cufí
commit e3b8fad9fa

View file

@ -2351,6 +2351,19 @@ int net_tcp_queue_data(struct net_context *context, struct net_pkt *pkt)
goto out;
}
if ((ret == -ENOBUFS) &&
(conn->send_data_total < (conn->unacked_len + len))) {
/* Some of the data has been sent, we cannot remove the
* whole chunk, the remainder portion is already
* in the send_data and will be transmitted upon a
* received ack or the next send call
*
* Set the return code back to 0 to pretend we just
* transmitted the chunk
*/
ret = 0;
}
if (ret == -ENOBUFS) {
/* Restore the original data so that we do not resend the pkt
* data multiple times.