lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Sun,  9 Aug 2009 21:48:43 +0200
From:	Gerrit Renker <gerrit@....abdn.ac.uk>
To:	dccp@...r.kernel.org
Cc:	netdev@...r.kernel.org, Gerrit Renker <gerrit@....abdn.ac.uk>
Subject: dccp-test-tree [PATCH 6/10] Extend the loss interval code to support ECN events

This updates the TFRC loss intervals code, which so far could only support
lost packets, to also handle the case of ECN-marked-CE packets:
 * the begin and length of the loss interval are different;
 * there are combinations of loss + ECN-marked-CE which the code does not
   currently consider (it is not worth the complexity), comments have been
   added to point this out.

Further changes:
----------------
The implementation of the "is the loss interval already closed?" check as per
RFC 4342, 10.2 has been improved to test the condition more efficiently.

Signed-off-by: Gerrit Renker <gerrit@....abdn.ac.uk>
---
 net/dccp/ccids/lib/loss_interval.c |   76 ++++++++++++++++++++++++++++--------
 1 files changed, 59 insertions(+), 17 deletions(-)

--- a/net/dccp/ccids/lib/loss_interval.c
+++ b/net/dccp/ccids/lib/loss_interval.c
@@ -124,12 +124,12 @@ void tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *skb)
 	tfrc_lh_calc_i_mean(lh);
 }
 
-/* Determine if `new_loss' does begin a new loss interval [RFC 4342, 10.2] */
-static inline u8 tfrc_lh_is_new_loss(struct tfrc_loss_interval *cur,
-				     struct tfrc_rx_hist_entry *new_loss)
+/* RFC 4342, 10.2: test for the existence of packet with sequence number S */
+static bool tfrc_lh_closed_check(struct tfrc_loss_interval *cur, const u8 ccval)
 {
-	return	dccp_delta_seqno(cur->li_seqno, new_loss->tfrchrx_seqno) > 0 &&
-		(cur->li_is_closed || SUB16(new_loss->tfrchrx_ccval, cur->li_ccval) > 4);
+	if (SUB16(ccval, cur->li_ccval) > 4)
+		cur->li_is_closed = true;
+	return cur->li_is_closed;
 }
 
 /** tfrc_lh_interval_add  -  Insert new record into the Loss Interval database
@@ -142,27 +142,69 @@ static inline u8 tfrc_lh_is_new_loss(struct tfrc_loss_interval *cur,
 bool tfrc_lh_interval_add(struct tfrc_loss_hist *lh, struct tfrc_rx_hist *rh,
 			  u32 (*calc_first_li)(struct sock *), struct sock *sk)
 {
-	struct tfrc_loss_interval *cur = tfrc_lh_peek(lh), *new;
+	struct tfrc_loss_interval *cur = tfrc_lh_peek(lh);
+	struct tfrc_rx_hist_entry *cong_evt;
+	u64 cong_evt_seqno;
+
+	/*
+	 * Determine if the new event is caused by a lost or ECN-marked packet.
+	 * Both events can coincide (e.g. if the third packet after a loss is
+	 * marked as CE). We avoid the complexity caused by such mixed cases:
+	 *   1) if the cause is a lost packet, we do not check whether it is
+	 *      also an ECN-marked packet (not necessary);
+	 *   2) calling this routine with a loss_count of 0..NDUPACK-1 implies
+	 *      that the cause is an ECN-marked-CE packet.
+	 *      FIXME: if in this case the loss_count is not 0, loss tracking is
+	 *      reset. This is a complex corner case (see packet_history.c) and
+	 *      hence currently not supported.
+	 */
+	if (rh->loss_count == TFRC_NDUPACK) {
+		/*
+		 * The sequence number of the first packet known to be lost is
+		 * the successor of the last packet received before the gap.
+		 */
+		cong_evt = tfrc_rx_hist_loss_prev(rh);
+		cong_evt_seqno = ADD48(cong_evt->tfrchrx_seqno, 1);
+	} else {
+		/*
+		 * ECN-marked packet. Since ECN-marks are reported as soon as a
+		 * packet is delivered, it is stored in the last-received entry.
+		 */
+		cong_evt = tfrc_rx_hist_last_rcv(rh);
+		cong_evt_seqno = cong_evt->tfrchrx_seqno;
+	}
 
-	if (cur != NULL && !tfrc_lh_is_new_loss(cur, tfrc_rx_hist_loss_prev(rh)))
-		return false;
+	/* Test if this event starts a new loss interval */
+	if (cur != NULL) {
+		s64 len = dccp_delta_seqno(cur->li_seqno, cong_evt_seqno);
+		if (len <= 0)
+			return false;
+
+		if (!tfrc_lh_closed_check(cur, cong_evt->tfrchrx_ccval))
+			return false;
 
-	new = tfrc_lh_demand_next(lh);
-	if (unlikely(new == NULL)) {
+		/* RFC 5348, 5.3: length between subsequent intervals */
+		cur->li_length = len;
+	}
+
+	/* Make the new interval the current one */
+	cur = tfrc_lh_demand_next(lh);
+	if (unlikely(cur == NULL)) {
 		DCCP_CRIT("Cannot allocate/add loss record.");
 		return false;
 	}
 
-	new->li_seqno	  = tfrc_rx_hist_loss_prev(rh)->tfrchrx_seqno;
-	new->li_ccval	  = tfrc_rx_hist_loss_prev(rh)->tfrchrx_ccval;
-	new->li_is_closed = 0;
+	cur->li_seqno	  = cong_evt_seqno;
+	cur->li_ccval	  = cong_evt->tfrchrx_ccval;
+	cur->li_is_closed = false;
 
 	if (++lh->counter == 1)
-		lh->i_mean = new->li_length = (*calc_first_li)(sk);
+		lh->i_mean = cur->li_length = (*calc_first_li)(sk);
 	else {
-		cur->li_length = dccp_delta_seqno(cur->li_seqno, new->li_seqno);
-		new->li_length = dccp_delta_seqno(new->li_seqno,
-				  tfrc_rx_hist_last_rcv(rh)->tfrchrx_seqno) + 1;
+		/* RFC 5348, 5.3: length of the open loss interval I_0 */
+		cur->li_length = dccp_delta_seqno(cur->li_seqno,
+				 tfrc_rx_hist_last_rcv(rh)->tfrchrx_seqno) + 1;
+
 		if (lh->counter > (2*LIH_SIZE))
 			lh->counter -= LIH_SIZE;
 
-- 
1.6.0.rc2

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ