Commit f74e91b6cca5889e667193c7e794186db73c2000

Authored by Gerrit Renker
Committed by David S. Miller
1 parent 6bb3ce25d0

dccp: Limit feature negotiation to connection setup phase

This patch limits feature (capability) negotation to the connection setup phase:

 1. Although it is theoretically possible to perform feature negotiation at any
    time (and RFC 4340 supports this), in practice this is prohibitively complex,
    as it requires to put traffic on hold for each new negotiation.
 2. As a byproduct of restricting feature negotiation to connection setup, the
    feature-negotiation retransmit timer is no longer required. This part is now
    mapped onto the protocol-level retransmission.
    Details indicating why timers are no longer needed can be found on
    http://www.erg.abdn.ac.uk/users/gerrit/dccp/notes/feature_negotiation/\
	                                      implementation_notes.html

This patch disables anytime negotiation, subsequent patches work out full
feature negotiation support for connection setup.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 3 changed files with 8 additions and 41 deletions Side-by-side Diff

... ... @@ -6,6 +6,8 @@
6 6 *
7 7 * ASSUMPTIONS
8 8 * -----------
  9 + * o Feature negotiation is coordinated with connection setup (as in TCP), wild
  10 + * changes of parameters of an established connection are not supported.
9 11 * o All currently known SP features have 1-byte quantities. If in the future
10 12 * extensions of RFCs 4340..42 define features with item lengths larger than
11 13 * one byte, a feature-specific extension of the code will be required.
... ... @@ -542,6 +544,9 @@
542 544 {
543 545 int rc;
544 546  
  547 + /* Ignore Change requests other than during connection setup */
  548 + if (sk->sk_state != DCCP_LISTEN && sk->sk_state != DCCP_REQUESTING)
  549 + return 0;
545 550 dccp_feat_debug(type, feature, *val);
546 551  
547 552 /* figure out if it's SP or NN feature */
... ... @@ -591,6 +596,9 @@
591 596 int found = 0;
592 597 int all_confirmed = 1;
593 598  
  599 + /* Ignore Confirm options other than during connection setup */
  600 + if (sk->sk_state != DCCP_LISTEN && sk->sk_state != DCCP_REQUESTING)
  601 + return 0;
594 602 dccp_feat_debug(type, feature, *val);
595 603  
596 604 /* locate our change request */
... ... @@ -623,17 +631,6 @@
623 631  
624 632 if (!opt->dccpop_conf)
625 633 all_confirmed = 0;
626   - }
627   -
628   - /* fix re-transmit timer */
629   - /* XXX gotta make sure that no option negotiation occurs during
630   - * connection shutdown. Consider that the CLOSEREQ is sent and timer is
631   - * on. if all options are confirmed it might kill timer which should
632   - * remain alive until close is received.
633   - */
634   - if (all_confirmed) {
635   - dccp_pr_debug("clear feat negotiation timer %p\n", sk);
636   - inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS);
637 634 }
638 635  
639 636 if (!found)
... ... @@ -489,7 +489,6 @@
489 489  
490 490 static int dccp_insert_options_feat(struct sock *sk, struct sk_buff *skb)
491 491 {
492   - struct dccp_sock *dp = dccp_sk(sk);
493 492 struct dccp_minisock *dmsk = dccp_msk(sk);
494 493 struct dccp_opt_pend *opt, *next;
495 494 int change = 0;
... ... @@ -528,23 +527,6 @@
528 527 opt->dccpop_len);
529 528 change++;
530 529 }
531   - }
532   -
533   - /* Retransmit timer.
534   - * If this is the master listening sock, we don't set a timer on it. It
535   - * should be fine because if the dude doesn't receive our RESPONSE
536   - * [which will contain the CHANGE] he will send another REQUEST which
537   - * will "retrnasmit" the change.
538   - */
539   - if (change && dp->dccps_role != DCCP_ROLE_LISTEN) {
540   - dccp_pr_debug("reset feat negotiation timer %p\n", sk);
541   -
542   - /* XXX don't reset the timer on re-transmissions. I.e. reset it
543   - * only when sending new stuff i guess. Currently the timer
544   - * never backs off because on re-transmission it just resets it!
545   - */
546   - inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
547   - inet_csk(sk)->icsk_rto, DCCP_RTO_MAX);
548 530 }
549 531  
550 532 return 0;
... ... @@ -87,17 +87,6 @@
87 87 {
88 88 struct inet_connection_sock *icsk = inet_csk(sk);
89 89  
90   - /* retransmit timer is used for feature negotiation throughout
91   - * connection. In this case, no packet is re-transmitted, but rather an
92   - * ack is generated and pending changes are placed into its options.
93   - */
94   - if (sk->sk_send_head == NULL) {
95   - dccp_pr_debug("feat negotiation retransmit timeout %p\n", sk);
96   - if (sk->sk_state == DCCP_OPEN)
97   - dccp_send_ack(sk);
98   - goto backoff;
99   - }
100   -
101 90 /*
102 91 * More than than 4MSL (8 minutes) has passed, a RESET(aborted) was
103 92 * sent, no need to retransmit, this sock is dead.
... ... @@ -126,7 +115,6 @@
126 115 return;
127 116 }
128 117  
129   -backoff:
130 118 icsk->icsk_backoff++;
131 119  
132 120 icsk->icsk_rto = min(icsk->icsk_rto << 1, DCCP_RTO_MAX);