From 522f1d095bf76dbe2430fb9a9a257c0f27033f31 Mon Sep 17 00:00:00 2001 From: Andrea Bittau Date: Sun, 26 Nov 2006 01:04:40 -0200 Subject: [DCCP] ackvec: Split long ack vectors across multiple options Ack vectors grow proportional to the window size. If an ack vector does not fit into a single option, it must be spread across multiple options. This patch will allow for windows to grow larger. Committer note: Simplified the patch a bit, original algorithm kept. Signed-off-by: Andrea Bittau Signed-off-by: Arnaldo Carvalho de Melo --- net/dccp/ackvec.c | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c index 41d34d1babc1..bdf1bb7a82c0 100644 --- a/net/dccp/ackvec.c +++ b/net/dccp/ackvec.c @@ -68,10 +68,15 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) { struct dccp_sock *dp = dccp_sk(sk); struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec; - int len = av->dccpav_vec_len + 2; + /* Figure out how many options do we need to represent the ackvec */ + const u16 nr_opts = (av->dccpav_vec_len + + DCCP_MAX_ACKVEC_OPT_LEN - 1) / + DCCP_MAX_ACKVEC_OPT_LEN; + u16 len = av->dccpav_vec_len + 2 * nr_opts, i; struct timeval now; u32 elapsed_time; - unsigned char *to, *from; + const unsigned char *tail, *from; + unsigned char *to; struct dccp_ackvec_record *avr; if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) @@ -90,24 +95,37 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) DCCP_SKB_CB(skb)->dccpd_opt_len += len; - to = skb_push(skb, len); - *to++ = DCCPO_ACK_VECTOR_0; - *to++ = len; - + to = skb_push(skb, len); len = av->dccpav_vec_len; from = av->dccpav_buf + av->dccpav_buf_head; + tail = av->dccpav_buf + DCCP_MAX_ACKVEC_LEN; + + for (i = 0; i < nr_opts; ++i) { + int copylen = len; + + if (len > DCCP_MAX_ACKVEC_OPT_LEN) + copylen = DCCP_MAX_ACKVEC_OPT_LEN; - /* Check if buf_head wraps */ - if ((int)av->dccpav_buf_head + len > DCCP_MAX_ACKVEC_LEN) { - const u32 tailsize = DCCP_MAX_ACKVEC_LEN - av->dccpav_buf_head; + *to++ = DCCPO_ACK_VECTOR_0; + *to++ = copylen + 2; + + /* Check if buf_head wraps */ + if (from + copylen > tail) { + const u16 tailsize = tail - from; + + memcpy(to, from, tailsize); + to += tailsize; + len -= tailsize; + copylen -= tailsize; + from = av->dccpav_buf; + } - memcpy(to, from, tailsize); - to += tailsize; - len -= tailsize; - from = av->dccpav_buf; + memcpy(to, from, copylen); + from += copylen; + to += copylen; + len -= copylen; } - memcpy(to, from, len); /* * From RFC 4340, A.2: * -- cgit v1.2.3-59-g8ed1b