aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/options.c
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2008-09-04 01:30:19 -0400
committerGerrit Renker <gerrit@erg.abdn.ac.uk>2008-09-04 01:45:36 -0400
commitd7dc7e5f49299739e610ea8febf9ea91a4dc1ae9 (patch)
tree30a2e1c3b9e99b1a386ca99efa71769415437885 /net/dccp/options.c
parent4829007c7bc689cbc290fc09eccbe90bd52c2a5e (diff)
dccp ccid-2: Implementation of circular Ack Vector buffer with overflow handling
This completes the implementation of a circular buffer for Ack Vectors, by extending the current (linear array-based) implementation. The changes are: (a) An `overflow' flag to deal with the case of overflow. As before, dynamic growth of the buffer will not be supported; but code will be added to deal robustly with overflowing Ack Vector buffers. (b) A `tail_seqno' field. When naively implementing the algorithm of Appendix A in RFC 4340, problems arise whenever subsequent Ack Vector records overlap, which can bring the entire run length calculation completely out of synch. (This is documented on http://www.erg.abdn.ac.uk/users/gerrit/dccp/notes/\ ack_vectors/tracking_tail_ackno/ .) (c) The buffer lengthi is now computed dynamically (i.e. current fill level), as the span between head to tail. As a result, dccp_ackvec_pending() is now simpler - the #ifdef is no longer necessary since buf_empty is always true when IP_DCCP_ACKVEC is not configured. Note on overflow handling: ------------------------- The Ack Vector code previously simply started to drop packets when the Ack Vector buffer overflowed. This means that the userspace application will not be able to receive, only because of an Ack Vector storage problem. Furthermore, overflow may be transient, so that applications may later recover from the overflow. Recovering from dropped packets is more difficult (e.g. video key frames). Hence the patch uses a different policy: when the buffer overflows, the oldest entries are subsequently overwritten. This has a higher chance of recovery. Details are on http://www.erg.abdn.ac.uk/users/gerrit/dccp/notes/ack_vectors/ Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Diffstat (limited to 'net/dccp/options.c')
-rw-r--r--net/dccp/options.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/net/dccp/options.c b/net/dccp/options.c
index 392d7db31342..3163ae980f16 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -432,9 +432,10 @@ static int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
432{ 432{
433 struct dccp_sock *dp = dccp_sk(sk); 433 struct dccp_sock *dp = dccp_sk(sk);
434 struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec; 434 struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec;
435 const u16 buflen = dccp_ackvec_buflen(av);
435 /* Figure out how many options do we need to represent the ackvec */ 436 /* Figure out how many options do we need to represent the ackvec */
436 const u8 nr_opts = DIV_ROUND_UP(av->av_vec_len, DCCP_SINGLE_OPT_MAXLEN); 437 const u8 nr_opts = DIV_ROUND_UP(buflen, DCCP_SINGLE_OPT_MAXLEN);
437 u16 len = av->av_vec_len + 2 * nr_opts; 438 u16 len = buflen + 2 * nr_opts;
438 u8 i, nonce = 0; 439 u8 i, nonce = 0;
439 const unsigned char *tail, *from; 440 const unsigned char *tail, *from;
440 unsigned char *to; 441 unsigned char *to;
@@ -445,7 +446,7 @@ static int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
445 DCCP_SKB_CB(skb)->dccpd_opt_len += len; 446 DCCP_SKB_CB(skb)->dccpd_opt_len += len;
446 447
447 to = skb_push(skb, len); 448 to = skb_push(skb, len);
448 len = av->av_vec_len; 449 len = buflen;
449 from = av->av_buf + av->av_buf_head; 450 from = av->av_buf + av->av_buf_head;
450 tail = av->av_buf + DCCPAV_MAX_ACKVEC_LEN; 451 tail = av->av_buf + DCCPAV_MAX_ACKVEC_LEN;
451 452
@@ -583,8 +584,7 @@ int dccp_insert_options(struct sock *sk, struct sk_buff *skb)
583 if (dccp_insert_option_timestamp(sk, skb)) 584 if (dccp_insert_option_timestamp(sk, skb))
584 return -1; 585 return -1;
585 586
586 } else if (dp->dccps_hc_rx_ackvec != NULL && 587 } else if (dccp_ackvec_pending(sk) &&
587 dccp_ackvec_pending(dp->dccps_hc_rx_ackvec) &&
588 dccp_insert_option_ackvec(sk, skb)) { 588 dccp_insert_option_ackvec(sk, skb)) {
589 return -1; 589 return -1;
590 } 590 }