Commit 0f9e5b573f7249b0e04a03457b55081d1f60f2bf

Authored by Gerrit Renker
Committed by David S. Miller
1 parent bfe24a6cc2

[DCCP]: Debug timeval operations

Problem:

 Most target types in the CCID3 code are u32, so subtle conversion errors
 can occur if signed time calculations yield negative results: the original
 values are lost in the conversion to unsigned, calculation errors go undetected.

 This patch therefore
   * sets all critical time types from unsigned to suseconds_t
   * avoids comparison between signed/unsigned via type-casting
   * provides ample warning messages in case time calculations are negative

 These warning messages can be removed at a later stage when the code
 has undergone more testing.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>

Showing 2 changed files with 33 additions and 24 deletions Side-by-side Diff

net/dccp/ccids/ccid3.c
... ... @@ -128,8 +128,8 @@
128 128 hctx->ccid3hctx_x = max_t(u64, hctx->ccid3hctx_x,
129 129 (hctx->ccid3hctx_s << 6)/TFRC_T_MBI);
130 130  
131   - } else if (timeval_delta(now, &hctx->ccid3hctx_t_ld) >=
132   - hctx->ccid3hctx_rtt) {
  131 + } else if (timeval_delta(now, &hctx->ccid3hctx_t_ld) -
  132 + (suseconds_t)hctx->ccid3hctx_rtt >= 0 ) {
133 133  
134 134 hctx->ccid3hctx_x = max(2 * min(hctx->ccid3hctx_x,
135 135 hctx->ccid3hctx_x_recv),
... ... @@ -271,7 +271,7 @@
271 271 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
272 272 struct dccp_tx_hist_entry *new_packet;
273 273 struct timeval now;
274   - long delay;
  274 + suseconds_t delay;
275 275  
276 276 BUG_ON(hctx == NULL);
277 277  
... ... @@ -331,7 +331,7 @@
331 331 * else
332 332 * // send the packet in (t_nom - t_now) milliseconds.
333 333 */
334   - if (delay - (long)hctx->ccid3hctx_delta >= 0)
  334 + if (delay - (suseconds_t)hctx->ccid3hctx_delta >= 0)
335 335 return delay / 1000L;
336 336 break;
337 337 case TFRC_SSTATE_TERM:
... ... @@ -353,7 +353,7 @@
353 353 const struct dccp_sock *dp = dccp_sk(sk);
354 354 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
355 355 struct timeval now;
356   - unsigned long quarter_rtt;
  356 + suseconds_t quarter_rtt;
357 357 struct dccp_tx_hist_entry *packet;
358 358  
359 359 BUG_ON(hctx == NULL);
... ... @@ -450,10 +450,8 @@
450 450 r_sample = timeval_delta(&now, &packet->dccphtx_tstamp);
451 451 t_elapsed = dp->dccps_options_received.dccpor_elapsed_time * 10;
452 452  
453   - if (unlikely(r_sample <= 0)) {
454   - DCCP_WARN("WARNING: R_sample (%ld) <= 0!\n", r_sample);
455   - r_sample = 0;
456   - } else if (unlikely(r_sample <= t_elapsed))
  453 + DCCP_BUG_ON(r_sample < 0);
  454 + if (unlikely(r_sample <= t_elapsed))
457 455 DCCP_WARN("WARNING: r_sample=%ldus <= t_elapsed=%ldus\n",
458 456 r_sample, t_elapsed);
459 457 else
... ... @@ -698,6 +696,7 @@
698 696 struct dccp_sock *dp = dccp_sk(sk);
699 697 struct dccp_rx_hist_entry *packet;
700 698 struct timeval now;
  699 + suseconds_t delta;
701 700  
702 701 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
703 702  
704 703  
... ... @@ -707,12 +706,12 @@
707 706 case TFRC_RSTATE_NO_DATA:
708 707 hcrx->ccid3hcrx_x_recv = 0;
709 708 break;
710   - case TFRC_RSTATE_DATA: {
711   - const u32 delta = timeval_delta(&now,
712   - &hcrx->ccid3hcrx_tstamp_last_feedback);
  709 + case TFRC_RSTATE_DATA:
  710 + delta = timeval_delta(&now,
  711 + &hcrx->ccid3hcrx_tstamp_last_feedback);
  712 + DCCP_BUG_ON(delta < 0);
713 713 hcrx->ccid3hcrx_x_recv =
714 714 scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
715   - }
716 715 break;
717 716 case TFRC_RSTATE_TERM:
718 717 DCCP_BUG("Illegal %s state TERM, sk=%p", dccp_role(sk), sk);
... ... @@ -730,9 +729,10 @@
730 729 hcrx->ccid3hcrx_ccval_last_counter = packet->dccphrx_ccval;
731 730 hcrx->ccid3hcrx_bytes_recv = 0;
732 731  
733   - /* Convert to multiples of 10us */
734   - hcrx->ccid3hcrx_elapsed_time =
735   - timeval_delta(&now, &packet->dccphrx_tstamp) / 10;
  732 + /* Elapsed time information [RFC 4340, 13.2] in units of 10 * usecs */
  733 + delta = timeval_delta(&now, &packet->dccphrx_tstamp);
  734 + DCCP_BUG_ON(delta < 0);
  735 + hcrx->ccid3hcrx_elapsed_time = delta / 10;
736 736  
737 737 if (hcrx->ccid3hcrx_p == 0)
738 738 hcrx->ccid3hcrx_pinv = ~0U; /* see RFC 4342, 8.5 */
... ... @@ -785,7 +785,8 @@
785 785 {
786 786 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
787 787 struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
788   - u32 rtt, delta, x_recv, p;
  788 + u32 x_recv, p;
  789 + suseconds_t rtt, delta;
789 790 struct timeval tstamp = { 0, };
790 791 int interval = 0;
791 792 int win_count = 0;
... ... @@ -830,8 +831,12 @@
830 831 DCCP_CRIT("tail is null\n");
831 832 return ~0;
832 833 }
833   - rtt = timeval_delta(&tstamp, &tail->dccphrx_tstamp) * 4 / interval;
834   - ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n",
  834 +
  835 + delta = timeval_delta(&tstamp, &tail->dccphrx_tstamp);
  836 + DCCP_BUG_ON(delta < 0);
  837 +
  838 + rtt = delta * 4 / interval;
  839 + ccid3_pr_debug("%s, sk=%p, approximated RTT to %ldus\n",
835 840 dccp_role(sk), sk, rtt);
836 841  
837 842 /*
838 843  
... ... @@ -849,8 +854,9 @@
849 854  
850 855 dccp_timestamp(sk, &tstamp);
851 856 delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback);
852   - x_recv = scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
  857 + DCCP_BUG_ON(delta <= 0);
853 858  
  859 + x_recv = scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
854 860 if (x_recv == 0) { /* would also trigger divide-by-zero */
855 861 DCCP_WARN("X_recv==0\n");
856 862 if ((x_recv = hcrx->ccid3hcrx_x_recv) == 0) {
... ... @@ -977,7 +983,8 @@
977 983 const struct dccp_options_received *opt_recv;
978 984 struct dccp_rx_hist_entry *packet;
979 985 struct timeval now;
980   - u32 p_prev, rtt_prev, r_sample, t_elapsed;
  986 + u32 p_prev, rtt_prev;
  987 + suseconds_t r_sample, t_elapsed;
981 988 int loss, payload_size;
982 989  
983 990 BUG_ON(hcrx == NULL);
984 991  
... ... @@ -997,8 +1004,9 @@
997 1004 r_sample = timeval_usecs(&now);
998 1005 t_elapsed = opt_recv->dccpor_elapsed_time * 10;
999 1006  
  1007 + DCCP_BUG_ON(r_sample < 0);
1000 1008 if (unlikely(r_sample <= t_elapsed))
1001   - DCCP_WARN("r_sample=%uus, t_elapsed=%uus\n",
  1009 + DCCP_WARN("r_sample=%ldus, t_elapsed=%ldus\n",
1002 1010 r_sample, t_elapsed);
1003 1011 else
1004 1012 r_sample -= t_elapsed;
... ... @@ -1051,8 +1059,8 @@
1051 1059 break;
1052 1060  
1053 1061 dccp_timestamp(sk, &now);
1054   - if (timeval_delta(&now, &hcrx->ccid3hcrx_tstamp_last_ack) >=
1055   - hcrx->ccid3hcrx_rtt) {
  1062 + if (timeval_delta(&now, &hcrx->ccid3hcrx_tstamp_last_ack) -
  1063 + (suseconds_t)hcrx->ccid3hcrx_rtt >= 0) {
1056 1064 hcrx->ccid3hcrx_tstamp_last_ack = now;
1057 1065 ccid3_hc_rx_send_feedback(sk);
1058 1066 }
... ... @@ -432,6 +432,7 @@
432 432 tv->tv_sec--;
433 433 tv->tv_usec += USEC_PER_SEC;
434 434 }
  435 + DCCP_BUG_ON(tv->tv_sec < 0);
435 436 }
436 437  
437 438 #ifdef CONFIG_SYSCTL