~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/dccp/ccids/ccid2.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /net/dccp/ccids/ccid2.c (Version linux-6.11-rc3) and /net/dccp/ccids/ccid2.c (Version linux-2.6.0)


  1 // SPDX-License-Identifier: GPL-2.0-or-later        1 
  2 /*                                                
  3  *  Copyright (c) 2005, 2006 Andrea Bittau <a.    
  4  *                                                
  5  *  Changes to meet Linux coding standards, an    
  6  *                                                
  7  *  Copyright (c) 2006 Arnaldo Carvalho de Mel    
  8  */                                               
  9                                                   
 10 /*                                                
 11  * This implementation should follow RFC 4341     
 12  */                                               
 13 #include <linux/slab.h>                           
 14 #include "../feat.h"                              
 15 #include "ccid2.h"                                
 16                                                   
 17                                                   
 18 #ifdef CONFIG_IP_DCCP_CCID2_DEBUG                 
 19 static bool ccid2_debug;                          
 20 #define ccid2_pr_debug(format, a...)    DCCP_P    
 21 #else                                             
 22 #define ccid2_pr_debug(format, a...)              
 23 #endif                                            
 24                                                   
 25 static int ccid2_hc_tx_alloc_seq(struct ccid2_    
 26 {                                                 
 27         struct ccid2_seq *seqp;                   
 28         int i;                                    
 29                                                   
 30         /* check if we have space to preserve     
 31         if (hc->tx_seqbufc >= (sizeof(hc->tx_s    
 32                                sizeof(struct c    
 33                 return -ENOMEM;                   
 34                                                   
 35         /* allocate buffer and initialize link    
 36         seqp = kmalloc_array(CCID2_SEQBUF_LEN,    
 37                              gfp_any());          
 38         if (seqp == NULL)                         
 39                 return -ENOMEM;                   
 40                                                   
 41         for (i = 0; i < (CCID2_SEQBUF_LEN - 1)    
 42                 seqp[i].ccid2s_next = &seqp[i     
 43                 seqp[i + 1].ccid2s_prev = &seq    
 44         }                                         
 45         seqp[CCID2_SEQBUF_LEN - 1].ccid2s_next    
 46         seqp->ccid2s_prev = &seqp[CCID2_SEQBUF    
 47                                                   
 48         /* This is the first allocation.  Init    
 49         if (hc->tx_seqbufc == 0)                  
 50                 hc->tx_seqh = hc->tx_seqt = se    
 51         else {                                    
 52                 /* link the existing list with    
 53                 hc->tx_seqh->ccid2s_next = seq    
 54                 seqp->ccid2s_prev = hc->tx_seq    
 55                                                   
 56                 hc->tx_seqt->ccid2s_prev = &se    
 57                 seqp[CCID2_SEQBUF_LEN - 1].cci    
 58         }                                         
 59                                                   
 60         /* store the original pointer to the b    
 61         hc->tx_seqbuf[hc->tx_seqbufc] = seqp;     
 62         hc->tx_seqbufc++;                         
 63                                                   
 64         return 0;                                 
 65 }                                                 
 66                                                   
 67 static int ccid2_hc_tx_send_packet(struct sock    
 68 {                                                 
 69         if (ccid2_cwnd_network_limited(ccid2_h    
 70                 return CCID_PACKET_WILL_DEQUEU    
 71         return CCID_PACKET_SEND_AT_ONCE;          
 72 }                                                 
 73                                                   
 74 static void ccid2_change_l_ack_ratio(struct so    
 75 {                                                 
 76         u32 max_ratio = DIV_ROUND_UP(ccid2_hc_    
 77                                                   
 78         /*                                        
 79          * Ensure that Ack Ratio does not exce    
 80          * RFC 4341, 6.1.2. We ignore the stat    
 81          * acceptable since this causes starva    
 82          * The same problem arises when Ack Ra    
 83          */                                       
 84         if (val == 0 || val > max_ratio) {        
 85                 DCCP_WARN("Limiting Ack Ratio     
 86                 val = max_ratio;                  
 87         }                                         
 88         dccp_feat_signal_nn_change(sk, DCCPF_A    
 89                                    min_t(u32,     
 90 }                                                 
 91                                                   
 92 static void ccid2_check_l_ack_ratio(struct soc    
 93 {                                                 
 94         struct ccid2_hc_tx_sock *hc = ccid2_hc    
 95                                                   
 96         /*                                        
 97          * After a loss, idle period, applicat    
 98          * need to check that the ack ratio is    
 99          * window. Otherwise, we will send an     
100          * packets and got no response because    
101          * packets yet.                           
102          * If the ack ratio does need to be re    
103          * the congestion window (or 1 if that    
104          * congestion window. This prevents pr    
105          */                                       
106         if (dccp_feat_nn_get(sk, DCCPF_ACK_RAT    
107                 ccid2_change_l_ack_ratio(sk, h    
108 }                                                 
109                                                   
110 static void ccid2_change_l_seq_window(struct s    
111 {                                                 
112         dccp_feat_signal_nn_change(sk, DCCPF_S    
113                                    clamp_val(v    
114                                                   
115 }                                                 
116                                                   
117 static void dccp_tasklet_schedule(struct sock     
118 {                                                 
119         struct tasklet_struct *t = &dccp_sk(sk    
120                                                   
121         if (!test_and_set_bit(TASKLET_STATE_SC    
122                 sock_hold(sk);                    
123                 __tasklet_schedule(t);            
124         }                                         
125 }                                                 
126                                                   
127 static void ccid2_hc_tx_rto_expire(struct time    
128 {                                                 
129         struct ccid2_hc_tx_sock *hc = from_tim    
130         struct sock *sk = hc->sk;                 
131         const bool sender_was_blocked = ccid2_    
132                                                   
133         bh_lock_sock(sk);                         
134         if (sock_owned_by_user(sk)) {             
135                 sk_reset_timer(sk, &hc->tx_rto    
136                 goto out;                         
137         }                                         
138                                                   
139         ccid2_pr_debug("RTO_EXPIRE\n");           
140                                                   
141         if (sk->sk_state == DCCP_CLOSED)          
142                 goto out;                         
143                                                   
144         /* back-off timer */                      
145         hc->tx_rto <<= 1;                         
146         if (hc->tx_rto > DCCP_RTO_MAX)            
147                 hc->tx_rto = DCCP_RTO_MAX;        
148                                                   
149         /* adjust pipe, cwnd etc */               
150         hc->tx_ssthresh = hc->tx_cwnd / 2;        
151         if (hc->tx_ssthresh < 2)                  
152                 hc->tx_ssthresh = 2;              
153         hc->tx_cwnd     = 1;                      
154         hc->tx_pipe     = 0;                      
155                                                   
156         /* clear state about stuff we sent */     
157         hc->tx_seqt = hc->tx_seqh;                
158         hc->tx_packets_acked = 0;                 
159                                                   
160         /* clear ack ratio state. */              
161         hc->tx_rpseq    = 0;                      
162         hc->tx_rpdupack = -1;                     
163         ccid2_change_l_ack_ratio(sk, 1);          
164                                                   
165         /* if we were blocked before, we may n    
166         if (sender_was_blocked)                   
167                 dccp_tasklet_schedule(sk);        
168         /* restart backed-off timer */            
169         sk_reset_timer(sk, &hc->tx_rtotimer, j    
170 out:                                              
171         bh_unlock_sock(sk);                       
172         sock_put(sk);                             
173 }                                                 
174                                                   
175 /*                                                
176  *      Congestion window validation (RFC 2861    
177  */                                               
178 static bool ccid2_do_cwv = true;                  
179 module_param(ccid2_do_cwv, bool, 0644);           
180 MODULE_PARM_DESC(ccid2_do_cwv, "Perform RFC286    
181                                                   
182 /**                                               
183  * ccid2_update_used_window  -  Track how much    
184  * @hc: socket to update window                   
185  * @new_wnd: new window values to add into the    
186  *                                                
187  * This is done in addition to CWV. The sender    
188  * packets may be in flight, to set the local     
189  * (RFC 4340, 7.5.2). The CWV mechanism is exp    
190  * maximum-used window. We use an EWMA low-pas    
191  */                                               
192 static void ccid2_update_used_window(struct cc    
193 {                                                 
194         hc->tx_expected_wnd = (3 * hc->tx_expe    
195 }                                                 
196                                                   
197 /* This borrows the code of tcp_cwnd_applicati    
198 static void ccid2_cwnd_application_limited(str    
199 {                                                 
200         struct ccid2_hc_tx_sock *hc = ccid2_hc    
201         /* don't reduce cwnd below the initial    
202         u32 init_win = rfc3390_bytes_to_packet    
203             win_used = max(hc->tx_cwnd_used, i    
204                                                   
205         if (win_used < hc->tx_cwnd) {             
206                 hc->tx_ssthresh = max(hc->tx_s    
207                                      (hc->tx_c    
208                 hc->tx_cwnd = (hc->tx_cwnd + w    
209         }                                         
210         hc->tx_cwnd_used  = 0;                    
211         hc->tx_cwnd_stamp = now;                  
212                                                   
213         ccid2_check_l_ack_ratio(sk);              
214 }                                                 
215                                                   
216 /* This borrows the code of tcp_cwnd_restart()    
217 static void ccid2_cwnd_restart(struct sock *sk    
218 {                                                 
219         struct ccid2_hc_tx_sock *hc = ccid2_hc    
220         u32 cwnd = hc->tx_cwnd, restart_cwnd,     
221             iwnd = rfc3390_bytes_to_packets(dc    
222         s32 delta = now - hc->tx_lsndtime;        
223                                                   
224         hc->tx_ssthresh = max(hc->tx_ssthresh,    
225                                                   
226         /* don't reduce cwnd below the initial    
227         restart_cwnd = min(cwnd, iwnd);           
228                                                   
229         while ((delta -= hc->tx_rto) >= 0 && c    
230                 cwnd >>= 1;                       
231         hc->tx_cwnd = max(cwnd, restart_cwnd);    
232         hc->tx_cwnd_stamp = now;                  
233         hc->tx_cwnd_used  = 0;                    
234                                                   
235         ccid2_check_l_ack_ratio(sk);              
236 }                                                 
237                                                   
238 static void ccid2_hc_tx_packet_sent(struct soc    
239 {                                                 
240         struct dccp_sock *dp = dccp_sk(sk);       
241         struct ccid2_hc_tx_sock *hc = ccid2_hc    
242         const u32 now = ccid2_jiffies32;          
243         struct ccid2_seq *next;                   
244                                                   
245         /* slow-start after idle periods (RFC     
246         if (ccid2_do_cwv && !hc->tx_pipe &&       
247             (s32)(now - hc->tx_lsndtime) >= hc    
248                 ccid2_cwnd_restart(sk, now);      
249                                                   
250         hc->tx_lsndtime = now;                    
251         hc->tx_pipe    += 1;                      
252                                                   
253         /* see whether cwnd was fully used (RF    
254         if (ccid2_cwnd_network_limited(hc)) {     
255                 ccid2_update_used_window(hc, h    
256                 hc->tx_cwnd_used  = 0;            
257                 hc->tx_cwnd_stamp = now;          
258         } else {                                  
259                 if (hc->tx_pipe > hc->tx_cwnd_    
260                         hc->tx_cwnd_used = hc-    
261                                                   
262                 ccid2_update_used_window(hc, h    
263                                                   
264                 if (ccid2_do_cwv && (s32)(now     
265                         ccid2_cwnd_application    
266         }                                         
267                                                   
268         hc->tx_seqh->ccid2s_seq   = dp->dccps_    
269         hc->tx_seqh->ccid2s_acked = 0;            
270         hc->tx_seqh->ccid2s_sent  = now;          
271                                                   
272         next = hc->tx_seqh->ccid2s_next;          
273         /* check if we need to alloc more spac    
274         if (next == hc->tx_seqt) {                
275                 if (ccid2_hc_tx_alloc_seq(hc))    
276                         DCCP_CRIT("packet hist    
277                         /* FIXME: find a more     
278                         return;                   
279                 }                                 
280                 next = hc->tx_seqh->ccid2s_nex    
281                 BUG_ON(next == hc->tx_seqt);      
282         }                                         
283         hc->tx_seqh = next;                       
284                                                   
285         ccid2_pr_debug("cwnd=%d pipe=%d\n", hc    
286                                                   
287         /*                                        
288          * FIXME: The code below is broken and    
289          * from the socket struct. The `acklos    
290          * and with arsent there are several p    
291          *  (i) it doesn't just count the numb    
292          *  (ii) it is expressed in # of packe    
293          *  comparison below uses the wrong fo    
294          *  comes up with the number K = cwnd     
295          *  of data with no lost or marked Ack    
296          *  consecutive Acks received without     
297          *  decreased by 1 when                   
298          *            arsent >=  K * cwnd / R     
299          *  where cwnd / R is the number of Ac    
300          *  (cf. RFC 4341, App. A). The proble    
301          *  - arsent counts other packets as w    
302          *  - the comparison uses a formula di    
303          *  - computing a cubic/quadratic equa    
304          *  Hence a different algorithm is nee    
305          */                                       
306 #if 0                                             
307         /* Ack Ratio.  Need to maintain a conc    
308         hc->tx_arsent++;                          
309         /* We had an ack loss in this window..    
310         if (hc->tx_ackloss) {                     
311                 if (hc->tx_arsent >= hc->tx_cw    
312                         hc->tx_arsent  = 0;       
313                         hc->tx_ackloss = 0;       
314                 }                                 
315         } else {                                  
316                 /* No acks lost up to now... *    
317                 /* decrease ack ratio if enoug    
318                 if (dp->dccps_l_ack_ratio > 1)    
319                         /* XXX don't calculate    
320                         int denom = dp->dccps_    
321                                     dp->dccps_    
322                                                   
323                         denom = hc->tx_cwnd *     
324                                                   
325                         if (hc->tx_arsent >= d    
326                                 ccid2_change_l    
327                                 hc->tx_arsent     
328                         }                         
329                 } else {                          
330                         /* we can't increase a    
331                         hc->tx_arsent = 0; /*     
332                 }                                 
333         }                                         
334 #endif                                            
335                                                   
336         sk_reset_timer(sk, &hc->tx_rtotimer, j    
337                                                   
338 #ifdef CONFIG_IP_DCCP_CCID2_DEBUG                 
339         do {                                      
340                 struct ccid2_seq *seqp = hc->t    
341                                                   
342                 while (seqp != hc->tx_seqh) {     
343                         ccid2_pr_debug("out se    
344                                        (unsign    
345                                        seqp->c    
346                         seqp = seqp->ccid2s_ne    
347                 }                                 
348         } while (0);                              
349         ccid2_pr_debug("=========\n");            
350 #endif                                            
351 }                                                 
352                                                   
353 /**                                               
354  * ccid2_rtt_estimator - Sample RTT and comput    
355  * @sk: socket to perform estimator on            
356  * @mrtt: measured RTT                            
357  *                                                
358  * This code is almost identical with TCP's tc    
359  * - it has a higher sampling frequency (recom    
360  * - the RTO does not collapse into RTT due to    
361  * - it is simple (cf. more complex proposals     
362  *   which suggests that the gain should be se    
363  * - in tests it was found to work well with C    
364  */                                               
365 static void ccid2_rtt_estimator(struct sock *s    
366 {                                                 
367         struct ccid2_hc_tx_sock *hc = ccid2_hc    
368         long m = mrtt ? : 1;                      
369                                                   
370         if (hc->tx_srtt == 0) {                   
371                 /* First measurement m */         
372                 hc->tx_srtt = m << 3;             
373                 hc->tx_mdev = m << 1;             
374                                                   
375                 hc->tx_mdev_max = max(hc->tx_m    
376                 hc->tx_rttvar   = hc->tx_mdev_    
377                                                   
378                 hc->tx_rtt_seq  = dccp_sk(sk)-    
379         } else {                                  
380                 /* Update scaled SRTT as SRTT     
381                 m -= (hc->tx_srtt >> 3);          
382                 hc->tx_srtt += m;                 
383                                                   
384                 /* Similarly, update scaled md    
385                 if (m < 0) {                      
386                         m = -m;                   
387                         m -= (hc->tx_mdev >> 2    
388                         /*                        
389                          * This neutralises RT    
390                          * (see P. Sarolahti,     
391                          * in Linux TCP", USEN    
392                          */                       
393                         if (m > 0)                
394                                 m >>= 3;          
395                 } else {                          
396                         m -= (hc->tx_mdev >> 2    
397                 }                                 
398                 hc->tx_mdev += m;                 
399                                                   
400                 if (hc->tx_mdev > hc->tx_mdev_    
401                         hc->tx_mdev_max = hc->    
402                         if (hc->tx_mdev_max >     
403                                 hc->tx_rttvar     
404                 }                                 
405                                                   
406                 /*                                
407                  * Decay RTTVAR at most once p    
408                  *  1) pipe <= cwnd <= Sequenc    
409                  *  2) AWL = GSS-W+1 <= GAR <=    
410                  * GAR is a useful bound for F    
411                  * AWL is probably too low her    
412                  */                               
413                 if (after48(dccp_sk(sk)->dccps    
414                         if (hc->tx_mdev_max <     
415                                 hc->tx_rttvar     
416                                                   
417                         hc->tx_rtt_seq  = dccp    
418                         hc->tx_mdev_max = tcp_    
419                 }                                 
420         }                                         
421                                                   
422         /*                                        
423          * Set RTO from SRTT and RTTVAR           
424          * As in TCP, 4 * RTTVAR >= TCP_RTO_MI    
425          * This agrees with RFC 4341, 5:          
426          *      "Because DCCP does not retrans    
427          *       TCP's recommended minimum tim    
428          */                                       
429         hc->tx_rto = (hc->tx_srtt >> 3) + hc->    
430                                                   
431         if (hc->tx_rto > DCCP_RTO_MAX)            
432                 hc->tx_rto = DCCP_RTO_MAX;        
433 }                                                 
434                                                   
435 static void ccid2_new_ack(struct sock *sk, str    
436                           unsigned int *maxinc    
437 {                                                 
438         struct ccid2_hc_tx_sock *hc = ccid2_hc    
439         struct dccp_sock *dp = dccp_sk(sk);       
440         int r_seq_used = hc->tx_cwnd / dp->dcc    
441                                                   
442         if (hc->tx_cwnd < dp->dccps_l_seq_win     
443             r_seq_used < dp->dccps_r_seq_win)     
444                 if (hc->tx_cwnd < hc->tx_ssthr    
445                         if (*maxincr > 0 && ++    
446                                 hc->tx_cwnd +=    
447                                 *maxincr    -=    
448                                 hc->tx_packets    
449                         }                         
450                 } else if (++hc->tx_packets_ac    
451                         hc->tx_cwnd += 1;         
452                         hc->tx_packets_acked =    
453                 }                                 
454         }                                         
455                                                   
456         /*                                        
457          * Adjust the local sequence window an    
458          * 5 times the number of packets in th    
459          */                                       
460         if (r_seq_used * CCID2_WIN_CHANGE_FACT    
461                 ccid2_change_l_ack_ratio(sk, d    
462         else if (r_seq_used * CCID2_WIN_CHANGE    
463                 ccid2_change_l_ack_ratio(sk, d    
464                                                   
465         if (hc->tx_cwnd * CCID2_WIN_CHANGE_FAC    
466                 ccid2_change_l_seq_window(sk,     
467         else if (hc->tx_cwnd * CCID2_WIN_CHANG    
468                 ccid2_change_l_seq_window(sk,     
469                                                   
470         /*                                        
471          * FIXME: RTT is sampled several times    
472          * entry in the Ack Vector), instead o    
473          * This causes the RTT to be over-esti    
474          * in the Ack Vector have earlier send    
475          * The cleanest solution is to not use    
476          * and instead use DCCP timestamps: re    
477          */                                       
478         ccid2_rtt_estimator(sk, ccid2_jiffies3    
479 }                                                 
480                                                   
481 static void ccid2_congestion_event(struct sock    
482 {                                                 
483         struct ccid2_hc_tx_sock *hc = ccid2_hc    
484                                                   
485         if ((s32)(seqp->ccid2s_sent - hc->tx_l    
486                 ccid2_pr_debug("Multiple losse    
487                 return;                           
488         }                                         
489                                                   
490         hc->tx_last_cong = ccid2_jiffies32;       
491                                                   
492         hc->tx_cwnd      = hc->tx_cwnd / 2 ? :    
493         hc->tx_ssthresh  = max(hc->tx_cwnd, 2U    
494                                                   
495         ccid2_check_l_ack_ratio(sk);              
496 }                                                 
497                                                   
498 static int ccid2_hc_tx_parse_options(struct so    
499                                      u8 option    
500 {                                                 
501         struct ccid2_hc_tx_sock *hc = ccid2_hc    
502                                                   
503         switch (option) {                         
504         case DCCPO_ACK_VECTOR_0:                  
505         case DCCPO_ACK_VECTOR_1:                  
506                 return dccp_ackvec_parsed_add(    
507                                                   
508         }                                         
509         return 0;                                 
510 }                                                 
511                                                   
512 static void ccid2_hc_tx_packet_recv(struct soc    
513 {                                                 
514         struct dccp_sock *dp = dccp_sk(sk);       
515         struct ccid2_hc_tx_sock *hc = ccid2_hc    
516         const bool sender_was_blocked = ccid2_    
517         struct dccp_ackvec_parsed *avp;           
518         u64 ackno, seqno;                         
519         struct ccid2_seq *seqp;                   
520         int done = 0;                             
521         unsigned int maxincr = 0;                 
522                                                   
523         /* check reverse path congestion */       
524         seqno = DCCP_SKB_CB(skb)->dccpd_seq;      
525                                                   
526         /* XXX this whole "algorithm" is broke    
527          * of the seqnos of the dupacks so tha    
528          * -sorbo.                                
529          */                                       
530         /* need to bootstrap */                   
531         if (hc->tx_rpdupack == -1) {              
532                 hc->tx_rpdupack = 0;              
533                 hc->tx_rpseq    = seqno;          
534         } else {                                  
535                 /* check if packet is consecut    
536                 if (dccp_delta_seqno(hc->tx_rp    
537                         hc->tx_rpseq = seqno;     
538                 /* it's a later packet */         
539                 else if (after48(seqno, hc->tx    
540                         hc->tx_rpdupack++;        
541                                                   
542                         /* check if we got eno    
543                         if (hc->tx_rpdupack >=    
544                                 hc->tx_rpdupac    
545                                 hc->tx_rpseq      
546 #ifdef __CCID2_COPES_GRACEFULLY_WITH_ACK_CONGE    
547                                 /*                
548                                  * FIXME: Ack     
549                                  * the current    
550                                  * Ack Ratios     
551                                  * and long RT    
552                                  * before open    
553                                  */               
554                                 ccid2_change_l    
555 #endif                                            
556                         }                         
557                 }                                 
558         }                                         
559                                                   
560         /* check forward path congestion */       
561         if (dccp_packet_without_ack(skb))         
562                 return;                           
563                                                   
564         /* still didn't send out new data pack    
565         if (hc->tx_seqh == hc->tx_seqt)           
566                 goto done;                        
567                                                   
568         ackno = DCCP_SKB_CB(skb)->dccpd_ack_se    
569         if (after48(ackno, hc->tx_high_ack))      
570                 hc->tx_high_ack = ackno;          
571                                                   
572         seqp = hc->tx_seqt;                       
573         while (before48(seqp->ccid2s_seq, ackn    
574                 seqp = seqp->ccid2s_next;         
575                 if (seqp == hc->tx_seqh) {        
576                         seqp = hc->tx_seqh->cc    
577                         break;                    
578                 }                                 
579         }                                         
580                                                   
581         /*                                        
582          * In slow-start, cwnd can increase up    
583          * packets per acknowledgement. Roundi    
584          * advanced when Ack Ratio is 1 and gi    
585          */                                       
586         if (hc->tx_cwnd < hc->tx_ssthresh)        
587                 maxincr = DIV_ROUND_UP(dp->dcc    
588                                                   
589         /* go through all ack vectors */          
590         list_for_each_entry(avp, &hc->tx_av_ch    
591                 /* go through this ack vector     
592                 for (; avp->len--; avp->vec++)    
593                         u64 ackno_end_rl = SUB    
594                                                   
595                                                   
596                         ccid2_pr_debug("ackvec    
597                                        (unsign    
598                                        dccp_ac    
599                                        dccp_ac    
600                         /* if the seqno we are    
601                          * current ackno, then    
602                          * seqnos.                
603                          */                       
604                         while (after48(seqp->c    
605                                 if (seqp == hc    
606                                         done =    
607                                         break;    
608                                 }                 
609                                 seqp = seqp->c    
610                         }                         
611                         if (done)                 
612                                 break;            
613                                                   
614                         /* check all seqnos in    
615                          * run length             
616                          */                       
617                         while (between48(seqp-    
618                                 const u8 state    
619                                                   
620                                 /* new packet     
621                                 if (state != D    
622                                     !seqp->cci    
623                                         if (st    
624                                                   
625                                                   
626                                         else      
627                                                   
628                                                   
629                                                   
630                                         seqp->    
631                                         ccid2_    
632                                                   
633                                         hc->tx    
634                                 }                 
635                                 if (seqp == hc    
636                                         done =    
637                                         break;    
638                                 }                 
639                                 seqp = seqp->c    
640                         }                         
641                         if (done)                 
642                                 break;            
643                                                   
644                         ackno = SUB48(ackno_en    
645                 }                                 
646                 if (done)                         
647                         break;                    
648         }                                         
649                                                   
650         /* The state about what is acked shoul    
651          * Check for NUMDUPACK                    
652          */                                       
653         seqp = hc->tx_seqt;                       
654         while (before48(seqp->ccid2s_seq, hc->    
655                 seqp = seqp->ccid2s_next;         
656                 if (seqp == hc->tx_seqh) {        
657                         seqp = hc->tx_seqh->cc    
658                         break;                    
659                 }                                 
660         }                                         
661         done = 0;                                 
662         while (1) {                               
663                 if (seqp->ccid2s_acked) {         
664                         done++;                   
665                         if (done == NUMDUPACK)    
666                                 break;            
667                 }                                 
668                 if (seqp == hc->tx_seqt)          
669                         break;                    
670                 seqp = seqp->ccid2s_prev;         
671         }                                         
672                                                   
673         /* If there are at least 3 acknowledge    
674          * below the last sequence number is c    
675          */                                       
676         if (done == NUMDUPACK) {                  
677                 struct ccid2_seq *last_acked =    
678                                                   
679                 /* check for lost packets */      
680                 while (1) {                       
681                         if (!seqp->ccid2s_acke    
682                                 ccid2_pr_debug    
683                                                   
684                                 /* XXX need to    
685                                  * order to de    
686                                  * one ack vec    
687                                  */               
688                                 ccid2_congesti    
689                                 hc->tx_pipe--;    
690                         }                         
691                         if (seqp == hc->tx_seq    
692                                 break;            
693                         seqp = seqp->ccid2s_pr    
694                 }                                 
695                                                   
696                 hc->tx_seqt = last_acked;         
697         }                                         
698                                                   
699         /* trim acked packets in tail */          
700         while (hc->tx_seqt != hc->tx_seqh) {      
701                 if (!hc->tx_seqt->ccid2s_acked    
702                         break;                    
703                                                   
704                 hc->tx_seqt = hc->tx_seqt->cci    
705         }                                         
706                                                   
707         /* restart RTO timer if not all outsta    
708         if (hc->tx_pipe == 0)                     
709                 sk_stop_timer(sk, &hc->tx_rtot    
710         else                                      
711                 sk_reset_timer(sk, &hc->tx_rto    
712 done:                                             
713         /* check if incoming Acks allow pendin    
714         if (sender_was_blocked && !ccid2_cwnd_    
715                 dccp_tasklet_schedule(sk);        
716         dccp_ackvec_parsed_cleanup(&hc->tx_av_    
717 }                                                 
718                                                   
719 static int ccid2_hc_tx_init(struct ccid *ccid,    
720 {                                                 
721         struct ccid2_hc_tx_sock *hc = ccid_pri    
722         struct dccp_sock *dp = dccp_sk(sk);       
723         u32 max_ratio;                            
724                                                   
725         /* RFC 4341, 5: initialise ssthresh to    
726         hc->tx_ssthresh = ~0U;                    
727                                                   
728         /* Use larger initial windows (RFC 434    
729         hc->tx_cwnd = rfc3390_bytes_to_packets    
730         hc->tx_expected_wnd = hc->tx_cwnd;        
731                                                   
732         /* Make sure that Ack Ratio is enabled    
733         max_ratio = DIV_ROUND_UP(hc->tx_cwnd,     
734         if (dp->dccps_l_ack_ratio == 0 || dp->    
735                 dp->dccps_l_ack_ratio = max_ra    
736                                                   
737         /* XXX init ~ to window size... */        
738         if (ccid2_hc_tx_alloc_seq(hc))            
739                 return -ENOMEM;                   
740                                                   
741         hc->tx_rto       = DCCP_TIMEOUT_INIT;     
742         hc->tx_rpdupack  = -1;                    
743         hc->tx_last_cong = hc->tx_lsndtime = h    
744         hc->tx_cwnd_used = 0;                     
745         hc->sk           = sk;                    
746         timer_setup(&hc->tx_rtotimer, ccid2_hc    
747         INIT_LIST_HEAD(&hc->tx_av_chunks);        
748         return 0;                                 
749 }                                                 
750                                                   
751 static void ccid2_hc_tx_exit(struct sock *sk)     
752 {                                                 
753         struct ccid2_hc_tx_sock *hc = ccid2_hc    
754         int i;                                    
755                                                   
756         sk_stop_timer(sk, &hc->tx_rtotimer);      
757                                                   
758         for (i = 0; i < hc->tx_seqbufc; i++)      
759                 kfree(hc->tx_seqbuf[i]);          
760         hc->tx_seqbufc = 0;                       
761         dccp_ackvec_parsed_cleanup(&hc->tx_av_    
762 }                                                 
763                                                   
764 static void ccid2_hc_rx_packet_recv(struct soc    
765 {                                                 
766         struct ccid2_hc_rx_sock *hc = ccid2_hc    
767                                                   
768         if (!dccp_data_packet(skb))               
769                 return;                           
770                                                   
771         if (++hc->rx_num_data_pkts >= dccp_sk(    
772                 dccp_send_ack(sk);                
773                 hc->rx_num_data_pkts = 0;         
774         }                                         
775 }                                                 
776                                                   
777 struct ccid_operations ccid2_ops = {              
778         .ccid_id                  = DCCPC_CCID    
779         .ccid_name                = "TCP-like"    
780         .ccid_hc_tx_obj_size      = sizeof(str    
781         .ccid_hc_tx_init          = ccid2_hc_t    
782         .ccid_hc_tx_exit          = ccid2_hc_t    
783         .ccid_hc_tx_send_packet   = ccid2_hc_t    
784         .ccid_hc_tx_packet_sent   = ccid2_hc_t    
785         .ccid_hc_tx_parse_options = ccid2_hc_t    
786         .ccid_hc_tx_packet_recv   = ccid2_hc_t    
787         .ccid_hc_rx_obj_size      = sizeof(str    
788         .ccid_hc_rx_packet_recv   = ccid2_hc_r    
789 };                                                
790                                                   
791 #ifdef CONFIG_IP_DCCP_CCID2_DEBUG                 
792 module_param(ccid2_debug, bool, 0644);            
793 MODULE_PARM_DESC(ccid2_debug, "Enable CCID-2 d    
794 #endif                                            
795                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php