[PATCH 1/1]: Fix bug in computing elapsed time

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



[CCID3]: Fix bug in computing elapsed time

This patch does the following:
 (a) modify existing patch set to dispense with interface
     timestamps (which were used to measure elapsed time,
     but did not find maintainer approval);
 (b) fix a bug in computing the elapsed time.

While (a) restores the original state of the CCID3 module with
regard to taking timestamps, (b) fixes a previously undiscovered bug:

 * the receive timestamp is taken when the skb enters the CCID3 module;
 * RFC 4342 requires to send an Elapsed Time estimate to the sender;
 * the bug is in computing the elapsed time as the time between `receiving'
   the packet (i.e. skb enters CCID module) and sending feedback,
     --> there is no layer-processing, queueing, or delay involved,
     --> hence the elapsed time is in the order of 1 function call
     --> this is in the dimension of 50 ... 100 usec
     --> which renders the use of elapsed time almost entirely useless.

The solution taken to fix (b) is in re-considering RFC 3448 in combination with
the requirements of RFC 4342:
 * RFC 3448, 3.2.1 requires the TFRC/CCID3 sender to provide timestamps;
 * RFC 4342, p. 10 makes it optional for the receiver to send either an Elapsed
   Time option (useless as per above), and/or a Timestamp Echo option;
 * the latter is automatically triggered in the DCCP module, since 
    - any received timestamp sets dccps_timestamp_echo and dccps_timestamp_time;
    - CCID3 feedback is sent via dccp_send_ack
    - dccp_send_ack sees that dccps_timestamp_echo is non-0 and calls 
      dccp_insert_option_timestamp_echo(), which supplies a timestamp echo option.

==> The result is a much more precise estimation of processing time, the problem
    of a useless time difference of 50...100usec disappears, as does the processing
    overhead to produce the negligible Elapsed Time estimate.

    As a further advantage, the now useless elapsed_time field can be removed from
    the socket, which slims the socket structure down by another full four bytes.

Signed-off-by: Gerrit Renker <gerrit@xxxxxxxxxxxxxx>    
---
 net/dccp/ccid.h        |   10 ++++++++++
 net/dccp/ccids/ccid3.c |   31 ++++++++++++++++++++-----------
 net/dccp/ccids/ccid3.h |    2 --
 net/dccp/options.c     |    6 ++++++
 4 files changed, 36 insertions(+), 13 deletions(-)

--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -43,6 +43,8 @@ struct ccid_operations {
 						    unsigned char* value);
 	int		(*ccid_hc_rx_insert_options)(struct sock *sk,
 						     struct sk_buff *skb);
+	int		(*ccid_hc_tx_insert_options)(struct sock *sk,
+						     struct sk_buff *skb);
 	void		(*ccid_hc_tx_packet_recv)(struct sock *sk,
 						  struct sk_buff *skb);
 	int		(*ccid_hc_tx_parse_options)(struct sock *sk,
@@ -152,6 +154,14 @@ static inline int ccid_hc_rx_insert_opti
 	return 0;
 }
 
+static inline int ccid_hc_tx_insert_options(struct ccid *ccid, struct sock *sk,
+					    struct sk_buff *skb)
+{
+	if (ccid->ccid_ops->ccid_hc_tx_insert_options != NULL)
+		return ccid->ccid_ops->ccid_hc_tx_insert_options(sk, skb);
+	return 0;
+}
+
 static inline void ccid_hc_rx_get_info(struct ccid *ccid, struct sock *sk,
 				       struct tcp_info *info)
 {
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -615,6 +615,23 @@ static int ccid3_hc_tx_parse_options(str
 	return rc;
 }
 
+static int ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb)
+{
+	if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
+		return 0;
+
+	/*
+	 * Timestamp as required by RFC 3448, 3.2.1
+	 * The receiver will reply with a Timestamp Echo option (RFC 4340, 13.1)
+	 * so that RFC 4340, 6. is also satisfied. In addition, we get a much
+	 * better estimate of the receiver processing time: since receive time-
+	 * stamps are taken in the CCID3 module, the elapsed time never amounts
+	 * to more than mere function processing time - which is negligible in
+	 * comparison to genuine layer-processing delays.
+	 */
+	return dccp_insert_option_timestamp(sk, skb);
+}
+
 static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk)
 {
 	struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid);
@@ -747,7 +764,7 @@ static void ccid3_hc_rx_send_feedback(st
 {
 	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
 	struct dccp_sock *dp = dccp_sk(sk);
-	struct timeval now, t_recv;
+	struct timeval now;
 	suseconds_t delta = 0;
 
 	dccp_timestamp(sk, &now);
@@ -771,12 +788,6 @@ static void ccid3_hc_rx_send_feedback(st
 	ccid3_pr_debug("Interval %ldusec, X_recv=%u, 1/p=%u\n", (long)delta,
 		       hcrx->ccid3hcrx_x_recv, hcrx->ccid3hcrx_pinv);
 
-	/* Elapsed time information [RFC 4340, 13.2] in units of 10 * usecs */
-	skb_get_timestamp(skb, &t_recv);
-	delta = timeval_delta(&now, &t_recv);
-	DCCP_BUG_ON(delta < 0);
-
-	hcrx->ccid3hcrx_elapsed_time	     = delta / 10;
 	hcrx->ccid3hcrx_tstamp_last_feedback = now;
 	hcrx->ccid3hcrx_ccval_last_counter   = dccp_hdr(skb)->dccph_ccval;
 	hcrx->ccid3hcrx_bytes_recv	     = 0;
@@ -801,10 +812,7 @@ static int ccid3_hc_rx_insert_options(st
 	x_recv = htonl(hcrx->ccid3hcrx_x_recv);
 	pinv   = htonl(hcrx->ccid3hcrx_pinv);
 
-	if ((hcrx->ccid3hcrx_elapsed_time != 0 &&
-	     dccp_insert_option_elapsed_time(sk, skb,
-					     hcrx->ccid3hcrx_elapsed_time)) ||
-	    dccp_insert_option_timestamp(sk, skb) ||
+	if (dccp_insert_option_timestamp(sk, skb) ||
 	    dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE,
 			       &pinv, sizeof(pinv)) ||
 	    dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE,
@@ -1192,6 +1200,7 @@ static struct ccid_operations ccid3 = {
 	.ccid_hc_tx_packet_sent	   = ccid3_hc_tx_packet_sent,
 	.ccid_hc_tx_packet_recv	   = ccid3_hc_tx_packet_recv,
 	.ccid_hc_tx_parse_options  = ccid3_hc_tx_parse_options,
+	.ccid_hc_tx_insert_options = ccid3_hc_tx_insert_options,
 	.ccid_hc_rx_obj_size	   = sizeof(struct ccid3_hc_rx_sock),
 	.ccid_hc_rx_init	   = ccid3_hc_rx_init,
 	.ccid_hc_rx_exit	   = ccid3_hc_rx_exit,
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -564,6 +564,12 @@ int dccp_insert_options(struct sock *sk,
 			return -1;
 	}
 
+	if (dp->dccps_hc_tx_insert_options) {
+		if (ccid_hc_tx_insert_options(dp->dccps_hc_tx_ccid, sk, skb))
+			return -1;
+		dp->dccps_hc_tx_insert_options = 0;
+	}
+
 	if (dp->dccps_hc_rx_insert_options) {
 		if (ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb))
 			return -1;
--- a/net/dccp/ccids/ccid3.h
+++ b/net/dccp/ccids/ccid3.h
@@ -140,7 +140,6 @@ enum ccid3_hc_rx_states {
  *  @ccid3hcrx_tstamp_last_ack  -  Time at which last feedback was sent
  *  @ccid3hcrx_hist  -  Packet history
  *  @ccid3hcrx_li_hist  -  Loss Interval History
- *  @ccid3hcrx_elapsed_time  -  Time since packet reception
  */
 struct ccid3_hc_rx_sock {
 	u64				ccid3hcrx_seqno_nonloss:48,
@@ -156,7 +155,6 @@ struct ccid3_hc_rx_sock {
 	struct timeval			ccid3hcrx_tstamp_last_ack;
 	struct list_head		ccid3hcrx_hist;
 	struct list_head		ccid3hcrx_li_hist;
-	u32				ccid3hcrx_elapsed_time;
 };
 
 static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk)
-
To unsubscribe from this list: send the line "unsubscribe dccp" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel]     [IETF DCCP]     [Linux Networking]     [Git]     [Security]     [Linux Assembly]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux