summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2023-06-27 19:45:59 -0700
committerFlorin Coras <fcoras@cisco.com>2023-06-27 20:34:21 -0700
commitc8767c42aadb5bd63206e117673991ef799e2d18 (patch)
treebcf39620e408a8580aa11b4b38f80d1fd1aea4db
parent31eaea9eef0594117e83733aa01f8bbda940e4da (diff)
session udp: add len check for tx dgrams
Type: fix Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: I35391fb8c39defbe0e57a241a357c3c98e8cef54
-rw-r--r--src/vnet/session/session.h13
-rw-r--r--src/vnet/session/session_node.c7
-rw-r--r--src/vnet/udp/udp.c4
3 files changed, 22 insertions, 2 deletions
diff --git a/src/vnet/session/session.h b/src/vnet/session/session.h
index e92b1f079d6..10bae273d85 100644
--- a/src/vnet/session/session.h
+++ b/src/vnet/session/session.h
@@ -582,6 +582,19 @@ transport_rx_fifo_has_ooo_data (transport_connection_t * tc)
return svm_fifo_has_ooo_data (s->rx_fifo);
}
+always_inline u32
+transport_tx_fifo_has_dgram (transport_connection_t *tc)
+{
+ session_t *s = session_get (tc->s_index, tc->thread_index);
+ u32 max_deq = svm_fifo_max_dequeue_cons (s->tx_fifo);
+ session_dgram_pre_hdr_t phdr;
+
+ if (max_deq <= sizeof (session_dgram_hdr_t))
+ return 0;
+ svm_fifo_peek (s->tx_fifo, 0, sizeof (phdr), (u8 *) &phdr);
+ return max_deq >= phdr.data_length + sizeof (session_dgram_hdr_t);
+}
+
always_inline void
transport_rx_fifo_req_deq_ntf (transport_connection_t *tc)
{
diff --git a/src/vnet/session/session_node.c b/src/vnet/session/session_node.c
index f652f2e9a1c..6d1b6bdf2ae 100644
--- a/src/vnet/session/session_node.c
+++ b/src/vnet/session/session_node.c
@@ -1236,6 +1236,13 @@ session_tx_set_dequeue_params (vlib_main_t * vm, session_tx_context_t * ctx,
ctx->max_len_to_snd = 0;
return;
}
+ /* We cannot be sure apps have not enqueued incomplete dgrams */
+ if (PREDICT_FALSE (ctx->max_dequeue <
+ ctx->hdr.data_length + sizeof (ctx->hdr)))
+ {
+ ctx->max_len_to_snd = 0;
+ return;
+ }
ASSERT (ctx->hdr.data_length > ctx->hdr.data_offset);
len = ctx->hdr.data_length - ctx->hdr.data_offset;
diff --git a/src/vnet/udp/udp.c b/src/vnet/udp/udp.c
index b3c410a2330..a8e013001e8 100644
--- a/src/vnet/udp/udp.c
+++ b/src/vnet/udp/udp.c
@@ -317,7 +317,7 @@ udp_push_header (transport_connection_t *tc, vlib_buffer_t **bs, u32 n_bufs)
if (PREDICT_FALSE (uc->flags & UDP_CONN_F_CLOSING))
{
- if (!transport_max_tx_dequeue (&uc->connection))
+ if (!transport_tx_fifo_has_dgram (&uc->connection))
udp_connection_program_cleanup (uc);
}
@@ -343,7 +343,7 @@ udp_session_close (u32 connection_index, u32 thread_index)
if (!uc || (uc->flags & UDP_CONN_F_MIGRATED))
return;
- if (!transport_max_tx_dequeue (&uc->connection))
+ if (!transport_tx_fifo_has_dgram (&uc->connection))
udp_connection_program_cleanup (uc);
else
uc->flags |= UDP_CONN_F_CLOSING;