Diff markup
1 /* 1 /*
2 * net/dccp/ackvec.c 2 * net/dccp/ackvec.c
3 * 3 *
4 * An implementation of the DCCP protocol 4 * An implementation of the DCCP protocol
5 * Copyright (c) 2005 Arnaldo Carvalho de Mel 5 * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
6 * 6 *
7 * This program is free software; you can 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Pub 8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; version 2 of 9 * Free Software Foundation; version 2 of the License;
10 */ 10 */
11 11
12 #include "ackvec.h" 12 #include "ackvec.h"
13 #include "dccp.h" 13 #include "dccp.h"
14 14
>> 15 #include <linux/dccp.h>
15 #include <linux/init.h> 16 #include <linux/init.h>
16 #include <linux/errno.h> 17 #include <linux/errno.h>
17 #include <linux/kernel.h> 18 #include <linux/kernel.h>
18 #include <linux/skbuff.h> 19 #include <linux/skbuff.h>
19 #include <linux/slab.h> 20 #include <linux/slab.h>
20 21
21 #include <net/sock.h> 22 #include <net/sock.h>
22 23
23 static struct kmem_cache *dccp_ackvec_slab; 24 static struct kmem_cache *dccp_ackvec_slab;
24 static struct kmem_cache *dccp_ackvec_record_s 25 static struct kmem_cache *dccp_ackvec_record_slab;
25 26
26 static struct dccp_ackvec_record *dccp_ackvec_ 27 static struct dccp_ackvec_record *dccp_ackvec_record_new(void)
27 { 28 {
28 struct dccp_ackvec_record *avr = 29 struct dccp_ackvec_record *avr =
29 kmem_cache_alloc(dccp_ 30 kmem_cache_alloc(dccp_ackvec_record_slab, GFP_ATOMIC);
30 31
31 if (avr != NULL) 32 if (avr != NULL)
32 INIT_LIST_HEAD(&avr->avr_node) 33 INIT_LIST_HEAD(&avr->avr_node);
33 34
34 return avr; 35 return avr;
35 } 36 }
36 37
37 static void dccp_ackvec_record_delete(struct d 38 static void dccp_ackvec_record_delete(struct dccp_ackvec_record *avr)
38 { 39 {
39 if (unlikely(avr == NULL)) 40 if (unlikely(avr == NULL))
40 return; 41 return;
41 /* Check if deleting a linked record * 42 /* Check if deleting a linked record */
42 WARN_ON(!list_empty(&avr->avr_node)); 43 WARN_ON(!list_empty(&avr->avr_node));
43 kmem_cache_free(dccp_ackvec_record_sla 44 kmem_cache_free(dccp_ackvec_record_slab, avr);
44 } 45 }
45 46
46 static void dccp_ackvec_insert_avr(struct dccp 47 static void dccp_ackvec_insert_avr(struct dccp_ackvec *av,
47 struct dccp 48 struct dccp_ackvec_record *avr)
48 { 49 {
49 /* 50 /*
50 * AVRs are sorted by seqno. Since we 51 * AVRs are sorted by seqno. Since we are sending them in order, we
51 * just add the AVR at the head of the 52 * just add the AVR at the head of the list.
52 * -sorbo. 53 * -sorbo.
53 */ 54 */
54 if (!list_empty(&av->av_records)) { 55 if (!list_empty(&av->av_records)) {
55 const struct dccp_ackvec_recor 56 const struct dccp_ackvec_record *head =
56 list_e 57 list_entry(av->av_records.next,
57 58 struct dccp_ackvec_record,
58 59 avr_node);
59 BUG_ON(before48(avr->avr_ack_s 60 BUG_ON(before48(avr->avr_ack_seqno, head->avr_ack_seqno));
60 } 61 }
61 62
62 list_add(&avr->avr_node, &av->av_recor 63 list_add(&avr->avr_node, &av->av_records);
63 } 64 }
64 65
65 int dccp_insert_option_ackvec(struct sock *sk, 66 int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
66 { 67 {
67 struct dccp_sock *dp = dccp_sk(sk); 68 struct dccp_sock *dp = dccp_sk(sk);
68 struct dccp_ackvec *av = dp->dccps_hc_ 69 struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec;
69 /* Figure out how many options do we n 70 /* Figure out how many options do we need to represent the ackvec */
70 const u8 nr_opts = DIV_ROUND_UP(av->av !! 71 const u16 nr_opts = DIV_ROUND_UP(av->av_vec_len, DCCP_MAX_ACKVEC_OPT_LEN);
71 u16 len = av->av_vec_len + 2 * nr_opts 72 u16 len = av->av_vec_len + 2 * nr_opts, i;
72 u32 elapsed_time; 73 u32 elapsed_time;
73 const unsigned char *tail, *from; 74 const unsigned char *tail, *from;
74 unsigned char *to; 75 unsigned char *to;
75 struct dccp_ackvec_record *avr; 76 struct dccp_ackvec_record *avr;
76 suseconds_t delta; 77 suseconds_t delta;
77 78
78 if (DCCP_SKB_CB(skb)->dccpd_opt_len + 79 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
79 return -1; 80 return -1;
80 81
81 delta = ktime_us_delta(ktime_get_real( 82 delta = ktime_us_delta(ktime_get_real(), av->av_time);
82 elapsed_time = delta / 10; 83 elapsed_time = delta / 10;
83 84
84 if (elapsed_time != 0 && 85 if (elapsed_time != 0 &&
85 dccp_insert_option_elapsed_time(sk 86 dccp_insert_option_elapsed_time(sk, skb, elapsed_time))
86 return -1; 87 return -1;
87 88
88 avr = dccp_ackvec_record_new(); 89 avr = dccp_ackvec_record_new();
89 if (avr == NULL) 90 if (avr == NULL)
90 return -1; 91 return -1;
91 92
92 DCCP_SKB_CB(skb)->dccpd_opt_len += len 93 DCCP_SKB_CB(skb)->dccpd_opt_len += len;
93 94
94 to = skb_push(skb, len); 95 to = skb_push(skb, len);
95 len = av->av_vec_len; 96 len = av->av_vec_len;
96 from = av->av_buf + av->av_buf_head; 97 from = av->av_buf + av->av_buf_head;
97 tail = av->av_buf + DCCP_MAX_ACKVEC_LE 98 tail = av->av_buf + DCCP_MAX_ACKVEC_LEN;
98 99
99 for (i = 0; i < nr_opts; ++i) { 100 for (i = 0; i < nr_opts; ++i) {
100 int copylen = len; 101 int copylen = len;
101 102
102 if (len > DCCP_SINGLE_OPT_MAXL !! 103 if (len > DCCP_MAX_ACKVEC_OPT_LEN)
103 copylen = DCCP_SINGLE_ !! 104 copylen = DCCP_MAX_ACKVEC_OPT_LEN;
104 105
105 *to++ = DCCPO_ACK_VECTOR_0; 106 *to++ = DCCPO_ACK_VECTOR_0;
106 *to++ = copylen + 2; 107 *to++ = copylen + 2;
107 108
108 /* Check if buf_head wraps */ 109 /* Check if buf_head wraps */
109 if (from + copylen > tail) { 110 if (from + copylen > tail) {
110 const u16 tailsize = t 111 const u16 tailsize = tail - from;
111 112
112 memcpy(to, from, tails 113 memcpy(to, from, tailsize);
113 to += tailsize; 114 to += tailsize;
114 len -= tailsize; 115 len -= tailsize;
115 copylen -= tailsize; 116 copylen -= tailsize;
116 from = av->av_buf; 117 from = av->av_buf;
117 } 118 }
118 119
119 memcpy(to, from, copylen); 120 memcpy(to, from, copylen);
120 from += copylen; 121 from += copylen;
121 to += copylen; 122 to += copylen;
122 len -= copylen; 123 len -= copylen;
123 } 124 }
124 125
125 /* 126 /*
126 * From RFC 4340, A.2: 127 * From RFC 4340, A.2:
127 * 128 *
128 * For each acknowledgement it se 129 * For each acknowledgement it sends, the HC-Receiver will add an
129 * acknowledgement record. ack_s 130 * acknowledgement record. ack_seqno will equal the HC-Receiver
130 * sequence number it used for th 131 * sequence number it used for the ack packet; ack_ptr will equal
131 * buf_head; ack_ackno will equal 132 * buf_head; ack_ackno will equal buf_ackno; and ack_nonce will
132 * equal buf_nonce. 133 * equal buf_nonce.
133 */ 134 */
134 avr->avr_ack_seqno = DCCP_SKB_CB(skb)- 135 avr->avr_ack_seqno = DCCP_SKB_CB(skb)->dccpd_seq;
135 avr->avr_ack_ptr = av->av_buf_head; 136 avr->avr_ack_ptr = av->av_buf_head;
136 avr->avr_ack_ackno = av->av_buf_ackno; 137 avr->avr_ack_ackno = av->av_buf_ackno;
137 avr->avr_ack_nonce = av->av_buf_nonce; 138 avr->avr_ack_nonce = av->av_buf_nonce;
138 avr->avr_sent_len = av->av_vec_len; 139 avr->avr_sent_len = av->av_vec_len;
139 140
140 dccp_ackvec_insert_avr(av, avr); 141 dccp_ackvec_insert_avr(av, avr);
141 142
142 dccp_pr_debug("%s ACK Vector 0, len=%d 143 dccp_pr_debug("%s ACK Vector 0, len=%d, ack_seqno=%llu, "
143 "ack_ackno=%llu\n", 144 "ack_ackno=%llu\n",
144 dccp_role(sk), avr->avr_ 145 dccp_role(sk), avr->avr_sent_len,
145 (unsigned long long)avr- 146 (unsigned long long)avr->avr_ack_seqno,
146 (unsigned long long)avr- 147 (unsigned long long)avr->avr_ack_ackno);
147 return 0; 148 return 0;
148 } 149 }
149 150
150 struct dccp_ackvec *dccp_ackvec_alloc(const gf 151 struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority)
151 { 152 {
152 struct dccp_ackvec *av = kmem_cache_al 153 struct dccp_ackvec *av = kmem_cache_alloc(dccp_ackvec_slab, priority);
153 154
154 if (av != NULL) { 155 if (av != NULL) {
155 av->av_buf_head = DCCP_MAX_AC 156 av->av_buf_head = DCCP_MAX_ACKVEC_LEN - 1;
156 av->av_buf_ackno = UINT48_MAX 157 av->av_buf_ackno = UINT48_MAX + 1;
157 av->av_buf_nonce = 0; 158 av->av_buf_nonce = 0;
158 av->av_time = ktime_set(0 159 av->av_time = ktime_set(0, 0);
159 av->av_vec_len = 0; 160 av->av_vec_len = 0;
160 INIT_LIST_HEAD(&av->av_records 161 INIT_LIST_HEAD(&av->av_records);
161 } 162 }
162 163
163 return av; 164 return av;
164 } 165 }
165 166
166 void dccp_ackvec_free(struct dccp_ackvec *av) 167 void dccp_ackvec_free(struct dccp_ackvec *av)
167 { 168 {
168 if (unlikely(av == NULL)) 169 if (unlikely(av == NULL))
169 return; 170 return;
170 171
171 if (!list_empty(&av->av_records)) { 172 if (!list_empty(&av->av_records)) {
172 struct dccp_ackvec_record *avr 173 struct dccp_ackvec_record *avr, *next;
173 174
174 list_for_each_entry_safe(avr, 175 list_for_each_entry_safe(avr, next, &av->av_records, avr_node) {
175 list_del_init(&avr->av 176 list_del_init(&avr->avr_node);
176 dccp_ackvec_record_del 177 dccp_ackvec_record_delete(avr);
177 } 178 }
178 } 179 }
179 180
180 kmem_cache_free(dccp_ackvec_slab, av); 181 kmem_cache_free(dccp_ackvec_slab, av);
181 } 182 }
182 183
183 static inline u8 dccp_ackvec_state(const struc 184 static inline u8 dccp_ackvec_state(const struct dccp_ackvec *av,
184 const u32 i 185 const u32 index)
185 { 186 {
186 return av->av_buf[index] & DCCP_ACKVEC 187 return av->av_buf[index] & DCCP_ACKVEC_STATE_MASK;
187 } 188 }
188 189
189 static inline u8 dccp_ackvec_len(const struct 190 static inline u8 dccp_ackvec_len(const struct dccp_ackvec *av,
190 const u32 ind 191 const u32 index)
191 { 192 {
192 return av->av_buf[index] & DCCP_ACKVEC 193 return av->av_buf[index] & DCCP_ACKVEC_LEN_MASK;
193 } 194 }
194 195
195 /* 196 /*
196 * If several packets are missing, the HC-Rece 197 * If several packets are missing, the HC-Receiver may prefer to enter multiple
197 * bytes with run length 0, rather than a sing 198 * bytes with run length 0, rather than a single byte with a larger run length;
198 * this simplifies table updates if one of the 199 * this simplifies table updates if one of the missing packets arrives.
199 */ 200 */
200 static inline int dccp_ackvec_set_buf_head_sta 201 static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av,
201 202 const unsigned int packets,
202 203 const unsigned char state)
203 { 204 {
204 unsigned int gap; 205 unsigned int gap;
205 long new_head; 206 long new_head;
206 207
207 if (av->av_vec_len + packets > DCCP_MA 208 if (av->av_vec_len + packets > DCCP_MAX_ACKVEC_LEN)
208 return -ENOBUFS; 209 return -ENOBUFS;
209 210
210 gap = packets - 1; 211 gap = packets - 1;
211 new_head = av->av_buf_head - packets; 212 new_head = av->av_buf_head - packets;
212 213
213 if (new_head < 0) { 214 if (new_head < 0) {
214 if (gap > 0) { 215 if (gap > 0) {
215 memset(av->av_buf, DCC 216 memset(av->av_buf, DCCP_ACKVEC_STATE_NOT_RECEIVED,
216 gap + new_head 217 gap + new_head + 1);
217 gap = -new_head; 218 gap = -new_head;
218 } 219 }
219 new_head += DCCP_MAX_ACKVEC_LE 220 new_head += DCCP_MAX_ACKVEC_LEN;
220 } 221 }
221 222
222 av->av_buf_head = new_head; 223 av->av_buf_head = new_head;
223 224
224 if (gap > 0) 225 if (gap > 0)
225 memset(av->av_buf + av->av_buf 226 memset(av->av_buf + av->av_buf_head + 1,
226 DCCP_ACKVEC_STATE_NOT_R 227 DCCP_ACKVEC_STATE_NOT_RECEIVED, gap);
227 228
228 av->av_buf[av->av_buf_head] = state; 229 av->av_buf[av->av_buf_head] = state;
229 av->av_vec_len += packets; 230 av->av_vec_len += packets;
230 return 0; 231 return 0;
231 } 232 }
232 233
233 /* 234 /*
234 * Implements the RFC 4340, Appendix A 235 * Implements the RFC 4340, Appendix A
235 */ 236 */
236 int dccp_ackvec_add(struct dccp_ackvec *av, co 237 int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
237 const u64 ackno, const u8 238 const u64 ackno, const u8 state)
238 { 239 {
239 /* 240 /*
240 * Check at the right places if the bu 241 * Check at the right places if the buffer is full, if it is, tell the
241 * caller to start dropping packets ti 242 * caller to start dropping packets till the HC-Sender acks our ACK
242 * vectors, when we will free up space 243 * vectors, when we will free up space in av_buf.
243 * 244 *
244 * We may well decide to do buffer com 245 * We may well decide to do buffer compression, etc, but for now lets
245 * just drop. 246 * just drop.
246 * 247 *
247 * From Appendix A.1.1 (`New Packets') 248 * From Appendix A.1.1 (`New Packets'):
248 * 249 *
249 * Of course, the circular buffer 250 * Of course, the circular buffer may overflow, either when the
250 * HC-Sender is sending data at a 251 * HC-Sender is sending data at a very high rate, when the
251 * HC-Receiver's acknowledgements 252 * HC-Receiver's acknowledgements are not reaching the HC-Sender,
252 * or when the HC-Sender is forge 253 * or when the HC-Sender is forgetting to acknowledge those acks
253 * (so the HC-Receiver is unable 254 * (so the HC-Receiver is unable to clean up old state). In this
254 * case, the HC-Receiver should e 255 * case, the HC-Receiver should either compress the buffer (by
255 * increasing run lengths when po 256 * increasing run lengths when possible), transfer its state to
256 * a larger buffer, or, as a last 257 * a larger buffer, or, as a last resort, drop all received
257 * packets, without processing th 258 * packets, without processing them whatsoever, until its buffer
258 * shrinks again. 259 * shrinks again.
259 */ 260 */
260 261
261 /* See if this is the first ackno bein 262 /* See if this is the first ackno being inserted */
262 if (av->av_vec_len == 0) { 263 if (av->av_vec_len == 0) {
263 av->av_buf[av->av_buf_head] = 264 av->av_buf[av->av_buf_head] = state;
264 av->av_vec_len = 1; 265 av->av_vec_len = 1;
265 } else if (after48(ackno, av->av_buf_a 266 } else if (after48(ackno, av->av_buf_ackno)) {
266 const u64 delta = dccp_delta_s 267 const u64 delta = dccp_delta_seqno(av->av_buf_ackno, ackno);
267 268
268 /* 269 /*
269 * Look if the state of this p 270 * Look if the state of this packet is the same as the
270 * previous ackno and if so if 271 * previous ackno and if so if we can bump the head len.
271 */ 272 */
272 if (delta == 1 && 273 if (delta == 1 &&
273 dccp_ackvec_state(av, av-> 274 dccp_ackvec_state(av, av->av_buf_head) == state &&
274 dccp_ackvec_len(av, av->av 275 dccp_ackvec_len(av, av->av_buf_head) < DCCP_ACKVEC_LEN_MASK)
275 av->av_buf[av->av_buf_ 276 av->av_buf[av->av_buf_head]++;
276 else if (dccp_ackvec_set_buf_h 277 else if (dccp_ackvec_set_buf_head_state(av, delta, state))
277 return -ENOBUFS; 278 return -ENOBUFS;
278 } else { 279 } else {
279 /* 280 /*
280 * A.1.2. Old Packets 281 * A.1.2. Old Packets
281 * 282 *
282 * When a packet with Seq 283 * When a packet with Sequence Number S <= buf_ackno
283 * arrives, the HC-Receiv 284 * arrives, the HC-Receiver will scan the table for
284 * the byte corresponding 285 * the byte corresponding to S. (Indexing structures
285 * could reduce the compl 286 * could reduce the complexity of this scan.)
286 */ 287 */
287 u64 delta = dccp_delta_seqno(a 288 u64 delta = dccp_delta_seqno(ackno, av->av_buf_ackno);
288 u32 index = av->av_buf_head; 289 u32 index = av->av_buf_head;
289 290
290 while (1) { 291 while (1) {
291 const u8 len = dccp_ac 292 const u8 len = dccp_ackvec_len(av, index);
292 const u8 av_state = dc !! 293 const u8 state = dccp_ackvec_state(av, index);
293 /* 294 /*
294 * valid packets not y 295 * valid packets not yet in av_buf have a reserved
295 * entry, with a len e 296 * entry, with a len equal to 0.
296 */ 297 */
297 if (av_state == DCCP_A !! 298 if (state == DCCP_ACKVEC_STATE_NOT_RECEIVED &&
298 len == 0 && delta 299 len == 0 && delta == 0) { /* Found our
299 300 reserved seat! */
300 dccp_pr_debug( 301 dccp_pr_debug("Found %llu reserved seat!\n",
301 302 (unsigned long long)ackno);
302 av->av_buf[ind 303 av->av_buf[index] = state;
303 goto out; 304 goto out;
304 } 305 }
305 /* len == 0 means one 306 /* len == 0 means one packet */
306 if (delta < len + 1) 307 if (delta < len + 1)
307 goto out_dupli 308 goto out_duplicate;
308 309
309 delta -= len + 1; 310 delta -= len + 1;
310 if (++index == DCCP_MA 311 if (++index == DCCP_MAX_ACKVEC_LEN)
311 index = 0; 312 index = 0;
312 } 313 }
313 } 314 }
314 315
315 av->av_buf_ackno = ackno; 316 av->av_buf_ackno = ackno;
316 av->av_time = ktime_get_real(); 317 av->av_time = ktime_get_real();
317 out: 318 out:
318 return 0; 319 return 0;
319 320
320 out_duplicate: 321 out_duplicate:
321 /* Duplicate packet */ 322 /* Duplicate packet */
322 dccp_pr_debug("Received a dup or alrea 323 dccp_pr_debug("Received a dup or already considered lost "
323 "packet: %llu\n", (unsig 324 "packet: %llu\n", (unsigned long long)ackno);
324 return -EILSEQ; 325 return -EILSEQ;
325 } 326 }
326 327
>> 328 #ifdef CONFIG_IP_DCCP_DEBUG
>> 329 void dccp_ackvector_print(const u64 ackno, const unsigned char *vector, int len)
>> 330 {
>> 331 dccp_pr_debug_cat("ACK vector len=%d, ackno=%llu |", len,
>> 332 (unsigned long long)ackno);
>> 333
>> 334 while (len--) {
>> 335 const u8 state = (*vector & DCCP_ACKVEC_STATE_MASK) >> 6;
>> 336 const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK;
>> 337
>> 338 dccp_pr_debug_cat("%d,%d|", state, rl);
>> 339 ++vector;
>> 340 }
>> 341
>> 342 dccp_pr_debug_cat("\n");
>> 343 }
>> 344
>> 345 void dccp_ackvec_print(const struct dccp_ackvec *av)
>> 346 {
>> 347 dccp_ackvector_print(av->av_buf_ackno,
>> 348 av->av_buf + av->av_buf_head,
>> 349 av->av_vec_len);
>> 350 }
>> 351 #endif
>> 352
327 static void dccp_ackvec_throw_record(struct dc 353 static void dccp_ackvec_throw_record(struct dccp_ackvec *av,
328 struct dc 354 struct dccp_ackvec_record *avr)
329 { 355 {
330 struct dccp_ackvec_record *next; 356 struct dccp_ackvec_record *next;
331 357
332 /* sort out vector length */ 358 /* sort out vector length */
333 if (av->av_buf_head <= avr->avr_ack_pt 359 if (av->av_buf_head <= avr->avr_ack_ptr)
334 av->av_vec_len = avr->avr_ack_ 360 av->av_vec_len = avr->avr_ack_ptr - av->av_buf_head;
335 else 361 else
336 av->av_vec_len = DCCP_MAX_ACKV 362 av->av_vec_len = DCCP_MAX_ACKVEC_LEN - 1 -
337 av->av_buf_he 363 av->av_buf_head + avr->avr_ack_ptr;
338 364
339 /* free records */ 365 /* free records */
340 list_for_each_entry_safe_from(avr, nex 366 list_for_each_entry_safe_from(avr, next, &av->av_records, avr_node) {
341 list_del_init(&avr->avr_node); 367 list_del_init(&avr->avr_node);
342 dccp_ackvec_record_delete(avr) 368 dccp_ackvec_record_delete(avr);
343 } 369 }
344 } 370 }
345 371
346 void dccp_ackvec_check_rcv_ackno(struct dccp_a 372 void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av, struct sock *sk,
347 const u64 ack 373 const u64 ackno)
348 { 374 {
349 struct dccp_ackvec_record *avr; 375 struct dccp_ackvec_record *avr;
350 376
351 /* 377 /*
352 * If we traverse backwards, it should 378 * If we traverse backwards, it should be faster when we have large
353 * windows. We will be receiving ACKs 379 * windows. We will be receiving ACKs for stuff we sent a while back
354 * -sorbo. 380 * -sorbo.
355 */ 381 */
356 list_for_each_entry_reverse(avr, &av-> 382 list_for_each_entry_reverse(avr, &av->av_records, avr_node) {
357 if (ackno == avr->avr_ack_seqn 383 if (ackno == avr->avr_ack_seqno) {
358 dccp_pr_debug("%s ACK 384 dccp_pr_debug("%s ACK packet 0, len=%d, ack_seqno=%llu, "
359 "ack_ack 385 "ack_ackno=%llu, ACKED!\n",
360 dccp_rol 386 dccp_role(sk), 1,
361 (unsigne 387 (unsigned long long)avr->avr_ack_seqno,
362 (unsigne 388 (unsigned long long)avr->avr_ack_ackno);
363 dccp_ackvec_throw_reco 389 dccp_ackvec_throw_record(av, avr);
364 break; 390 break;
365 } else if (avr->avr_ack_seqno 391 } else if (avr->avr_ack_seqno > ackno)
366 break; /* old news */ 392 break; /* old news */
367 } 393 }
368 } 394 }
369 395
370 static void dccp_ackvec_check_rcv_ackvector(st 396 static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av,
371 st 397 struct sock *sk, u64 *ackno,
372 co 398 const unsigned char len,
373 co 399 const unsigned char *vector)
374 { 400 {
375 unsigned char i; 401 unsigned char i;
376 struct dccp_ackvec_record *avr; 402 struct dccp_ackvec_record *avr;
377 403
378 /* Check if we actually sent an ACK ve 404 /* Check if we actually sent an ACK vector */
379 if (list_empty(&av->av_records)) 405 if (list_empty(&av->av_records))
380 return; 406 return;
381 407
382 i = len; 408 i = len;
383 /* 409 /*
384 * XXX 410 * XXX
385 * I think it might be more efficient 411 * I think it might be more efficient to work backwards. See comment on
386 * rcv_ackno. -sorbo. 412 * rcv_ackno. -sorbo.
387 */ 413 */
388 avr = list_entry(av->av_records.next, 414 avr = list_entry(av->av_records.next, struct dccp_ackvec_record, avr_node);
389 while (i--) { 415 while (i--) {
390 const u8 rl = *vector & DCCP_A 416 const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK;
391 u64 ackno_end_rl; 417 u64 ackno_end_rl;
392 418
393 dccp_set_seqno(&ackno_end_rl, 419 dccp_set_seqno(&ackno_end_rl, *ackno - rl);
394 420
395 /* 421 /*
396 * If our AVR sequence number 422 * If our AVR sequence number is greater than the ack, go
397 * forward in the AVR list unt 423 * forward in the AVR list until it is not so.
398 */ 424 */
399 list_for_each_entry_from(avr, 425 list_for_each_entry_from(avr, &av->av_records, avr_node) {
400 if (!after48(avr->avr_ 426 if (!after48(avr->avr_ack_seqno, *ackno))
401 goto found; 427 goto found;
402 } 428 }
403 /* End of the av_records list, 429 /* End of the av_records list, not found, exit */
404 break; 430 break;
405 found: 431 found:
406 if (between48(avr->avr_ack_seq 432 if (between48(avr->avr_ack_seqno, ackno_end_rl, *ackno)) {
407 const u8 state = *vect 433 const u8 state = *vector & DCCP_ACKVEC_STATE_MASK;
408 if (state != DCCP_ACKV 434 if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED) {
409 dccp_pr_debug( 435 dccp_pr_debug("%s ACK vector 0, len=%d, "
410 436 "ack_seqno=%llu, ack_ackno=%llu, "
411 437 "ACKED!\n",
412 438 dccp_role(sk), len,
413 439 (unsigned long long)
414 440 avr->avr_ack_seqno,
415 441 (unsigned long long)
416 442 avr->avr_ack_ackno);
417 dccp_ackvec_th 443 dccp_ackvec_throw_record(av, avr);
418 break; 444 break;
419 } 445 }
420 /* 446 /*
421 * If it wasn't receiv 447 * If it wasn't received, continue scanning... we might
422 * find another one. 448 * find another one.
423 */ 449 */
424 } 450 }
425 451
426 dccp_set_seqno(ackno, ackno_en 452 dccp_set_seqno(ackno, ackno_end_rl - 1);
427 ++vector; 453 ++vector;
428 } 454 }
429 } 455 }
430 456
431 int dccp_ackvec_parse(struct sock *sk, const s 457 int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb,
432 u64 *ackno, const u8 opt 458 u64 *ackno, const u8 opt, const u8 *value, const u8 len)
433 { 459 {
434 if (len > DCCP_SINGLE_OPT_MAXLEN) !! 460 if (len > DCCP_MAX_ACKVEC_OPT_LEN)
435 return -1; 461 return -1;
436 462
437 /* dccp_ackvector_print(DCCP_SKB_CB(sk 463 /* dccp_ackvector_print(DCCP_SKB_CB(skb)->dccpd_ack_seq, value, len); */
438 dccp_ackvec_check_rcv_ackvector(dccp_s 464 dccp_ackvec_check_rcv_ackvector(dccp_sk(sk)->dccps_hc_rx_ackvec, sk,
439 ackno, 465 ackno, len, value);
440 return 0; 466 return 0;
441 } 467 }
442 468
443 int __init dccp_ackvec_init(void) 469 int __init dccp_ackvec_init(void)
444 { 470 {
445 dccp_ackvec_slab = kmem_cache_create(" 471 dccp_ackvec_slab = kmem_cache_create("dccp_ackvec",
446 s 472 sizeof(struct dccp_ackvec), 0,
447 S 473 SLAB_HWCACHE_ALIGN, NULL);
448 if (dccp_ackvec_slab == NULL) 474 if (dccp_ackvec_slab == NULL)
449 goto out_err; 475 goto out_err;
450 476
451 dccp_ackvec_record_slab = 477 dccp_ackvec_record_slab =
452 kmem_cache_create("dcc 478 kmem_cache_create("dccp_ackvec_record",
453 size 479 sizeof(struct dccp_ackvec_record),
454 0, S 480 0, SLAB_HWCACHE_ALIGN, NULL);
455 if (dccp_ackvec_record_slab == NULL) 481 if (dccp_ackvec_record_slab == NULL)
456 goto out_destroy_slab; 482 goto out_destroy_slab;
457 483
458 return 0; 484 return 0;
459 485
460 out_destroy_slab: 486 out_destroy_slab:
461 kmem_cache_destroy(dccp_ackvec_slab); 487 kmem_cache_destroy(dccp_ackvec_slab);
462 dccp_ackvec_slab = NULL; 488 dccp_ackvec_slab = NULL;
463 out_err: 489 out_err:
464 DCCP_CRIT("Unable to create Ack Vector 490 DCCP_CRIT("Unable to create Ack Vector slab cache");
465 return -ENOBUFS; 491 return -ENOBUFS;
466 } 492 }
467 493
468 void dccp_ackvec_exit(void) 494 void dccp_ackvec_exit(void)
469 { 495 {
470 if (dccp_ackvec_slab != NULL) { 496 if (dccp_ackvec_slab != NULL) {
471 kmem_cache_destroy(dccp_ackvec 497 kmem_cache_destroy(dccp_ackvec_slab);
472 dccp_ackvec_slab = NULL; 498 dccp_ackvec_slab = NULL;
473 } 499 }
474 if (dccp_ackvec_record_slab != NULL) { 500 if (dccp_ackvec_record_slab != NULL) {
475 kmem_cache_destroy(dccp_ackvec 501 kmem_cache_destroy(dccp_ackvec_record_slab);
476 dccp_ackvec_record_slab = NULL 502 dccp_ackvec_record_slab = NULL;
477 } 503 }
478 } 504 }
479 505
|
This page was automatically generated by the
LXR engine.
|