Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dccp ccid-3: remove dead states

This patch is thanks to an investigation by Leandro Sales de Melo and his
colleagues. They worked out two state diagrams which highlight the fact that
the xxx_TERM states in CCID-3/4 are in fact not necessary.

And this can be confirmed by in turn looking at the code: the xxx_TERM states
are only ever set in ccid3_hc_{rx,tx}_exit(): when CCID-3 sets the state
to xxx_TERM, it is at a time where no more processing should be going on,
hence it is not necessary to introduce a dedicated exit state - this is already
implied by unloading the CCID.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>

+9 -30
+9 -28
net/dccp/ccids/ccid3.c
··· 54 54 [TFRC_SSTATE_NO_SENT] = "NO_SENT", 55 55 [TFRC_SSTATE_NO_FBACK] = "NO_FBACK", 56 56 [TFRC_SSTATE_FBACK] = "FBACK", 57 - [TFRC_SSTATE_TERM] = "TERM", 58 57 }; 59 58 60 59 return ccid3_state_names[state]; ··· 207 208 ccid3_pr_debug("%s(%p, state=%s) - entry\n", dccp_role(sk), sk, 208 209 ccid3_tx_state_name(hc->tx_state)); 209 210 211 + /* Ignore and do not restart after leaving the established state */ 212 + if ((1 << sk->sk_state) & ~(DCCPF_OPEN | DCCPF_PARTOPEN)) 213 + goto out; 214 + 215 + /* Reset feedback state to "no feedback received" */ 210 216 if (hc->tx_state == TFRC_SSTATE_FBACK) 211 217 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK); 212 - else if (hc->tx_state != TFRC_SSTATE_NO_FBACK) 213 - goto out; 214 218 215 219 /* 216 220 * Determine new allowed sending rate X as per draft rfc3448bis-00, 4.4 ··· 289 287 if (unlikely(skb->len == 0)) 290 288 return -EBADMSG; 291 289 292 - switch (hc->tx_state) { 293 - case TFRC_SSTATE_NO_SENT: 290 + if (hc->tx_state == TFRC_SSTATE_NO_SENT) { 294 291 sk_reset_timer(sk, &hc->tx_no_feedback_timer, (jiffies + 295 292 usecs_to_jiffies(TFRC_INITIAL_TIMEOUT))); 296 293 hc->tx_last_win_count = 0; ··· 324 323 ccid3_update_send_interval(hc); 325 324 326 325 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK); 327 - break; 328 - case TFRC_SSTATE_NO_FBACK: 329 - case TFRC_SSTATE_FBACK: 326 + 327 + } else { 330 328 delay = ktime_us_delta(hc->tx_t_nom, now); 331 329 ccid3_pr_debug("delay=%ld\n", (long)delay); 332 330 /* ··· 340 340 return (u32)delay / USEC_PER_MSEC; 341 341 342 342 ccid3_hc_tx_update_win_count(hc, now); 343 - break; 344 - case TFRC_SSTATE_TERM: 345 - DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk); 346 - return -EINVAL; 347 343 } 348 344 349 345 /* prepare to send now (add options etc.) */ ··· 375 379 if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK || 376 380 DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK)) 377 381 return; 378 - /* ... and only in the established state */ 379 - if (hc->tx_state != TFRC_SSTATE_FBACK && 380 - hc->tx_state != TFRC_SSTATE_NO_FBACK) 381 - return; 382 - 383 382 /* 384 383 * Locate the acknowledged packet in the TX history. 385 384 * ··· 520 529 { 521 530 struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); 522 531 523 - ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM); 524 532 sk_stop_timer(sk, &hc->tx_no_feedback_timer); 525 - 526 533 tfrc_tx_hist_purge(&hc->tx_hist); 527 534 } 528 535 ··· 579 590 static const char *const ccid3_rx_state_names[] = { 580 591 [TFRC_RSTATE_NO_DATA] = "NO_DATA", 581 592 [TFRC_RSTATE_DATA] = "DATA", 582 - [TFRC_RSTATE_TERM] = "TERM", 583 593 }; 584 594 585 595 return ccid3_rx_state_names[state]; ··· 604 616 { 605 617 struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk); 606 618 struct dccp_sock *dp = dccp_sk(sk); 607 - ktime_t now; 619 + ktime_t now = ktime_get_real(); 608 620 s64 delta = 0; 609 - 610 - if (unlikely(hc->rx_state == TFRC_RSTATE_TERM)) 611 - return; 612 - 613 - now = ktime_get_real(); 614 621 615 622 switch (fbtype) { 616 623 case CCID3_FBACK_INITIAL: ··· 809 826 static void ccid3_hc_rx_exit(struct sock *sk) 810 827 { 811 828 struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk); 812 - 813 - ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM); 814 829 815 830 tfrc_rx_hist_purge(&hc->rx_hist); 816 831 tfrc_lh_cleanup(&hc->rx_li_hist);
-2
net/dccp/ccids/ccid3.h
··· 77 77 TFRC_SSTATE_NO_SENT = 1, 78 78 TFRC_SSTATE_NO_FBACK, 79 79 TFRC_SSTATE_FBACK, 80 - TFRC_SSTATE_TERM, 81 80 }; 82 81 83 82 /** ··· 129 130 enum ccid3_hc_rx_states { 130 131 TFRC_RSTATE_NO_DATA = 1, 131 132 TFRC_RSTATE_DATA, 132 - TFRC_RSTATE_TERM = 127, 133 133 }; 134 134 135 135 /**