Commit 0f9e5b573f7249b0e04a03457b55081d1f60f2bf
Committed by
David S. Miller
1 parent
bfe24a6cc2
Exists in
master
and in
7 other branches
[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 | } |