[strongSwan-dev] [PATCH 2/5] ikev1: Fix code when to send fragments

Volker Rümelin vr_strongswan at t-online.de
Mon Mar 10 22:32:29 CET 2014


The old code could send unfragmented packets up to four bytes larger
than maximum fragment size.

As a side effect it also prevents a division by zero if someone by
mistake sets charon.fragment_size = 0 in strongswan.conf.
charon.fragment_size = 0 now disables fragmentation.
---
 src/libcharon/sa/ikev1/task_manager_v1.c | 43 ++++++++++++++++++++++++--------
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/src/libcharon/sa/ikev1/task_manager_v1.c b/src/libcharon/sa/ikev1/task_manager_v1.c
index 8fc158b..7e5b08d 100644
--- a/src/libcharon/sa/ikev1/task_manager_v1.c
+++ b/src/libcharon/sa/ikev1/task_manager_v1.c
@@ -404,14 +404,13 @@ static bool send_fragment(private_task_manager_t *this, bool request,
 }
 
 /**
- * Send a packet, if supported and required do so in fragments
+ * Get the packet fragment size. A fragment size of 0 disables fragmentation.
  */
-static bool send_packet(private_task_manager_t *this, bool request,
-						packet_t *packet)
+static size_t get_fragsize(private_task_manager_t *this, packet_t *packet)
 {
 	bool use_frags = FALSE;
 	ike_cfg_t *ike_cfg;
-	chunk_t data;
+	size_t frag_size = 0;
 
 	ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
 	if (ike_cfg)
@@ -429,12 +428,9 @@ static bool send_packet(private_task_manager_t *this, bool request,
 				break;
 		}
 	}
-	data = packet->get_data(packet);
-	if (data.len > this->frag.size && use_frags)
+
+	if (use_frags)
 	{
-		fragment_payload_t *fragment;
-		u_int8_t num, count;
-		size_t len, frag_size;
 		host_t *src, *dst;
 
 		src = packet->get_source(packet);
@@ -442,10 +438,37 @@ static bool send_packet(private_task_manager_t *this, bool request,
 
 		frag_size = this->frag.size;
 		if (dst->get_port(dst) != IKEV2_UDP_PORT &&
-			src->get_port(src) != IKEV2_UDP_PORT)
+			src->get_port(src) != IKEV2_UDP_PORT &&
+			frag_size > 4)
 		{	/* reduce size due to non-ESP marker */
 			frag_size -= 4;
 		}
+	}
+
+	return frag_size;
+}
+
+/**
+ * Send a packet, if supported and required do so in fragments
+ */
+static bool send_packet(private_task_manager_t *this, bool request,
+						packet_t *packet)
+{
+	chunk_t data;
+	size_t frag_size;
+
+	data = packet->get_data(packet);
+	frag_size = get_fragsize(this, packet);
+	if (frag_size > 0 && data.len > frag_size)
+	{
+		fragment_payload_t *fragment;
+		u_int8_t num, count;
+		size_t len;
+		host_t *src, *dst;
+
+		src = packet->get_source(packet);
+		dst = packet->get_destination(packet);
+
 		count = data.len / frag_size + (data.len % frag_size ? 1 : 0);
 
 		DBG1(DBG_IKE, "sending IKE message with length of %zu bytes in "
-- 
1.8.4.5




More information about the Dev mailing list