aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2008-11-12 03:42:58 -0500
committerDavid S. Miller <davem@davemloft.net>2008-11-12 03:42:58 -0500
commitf74e91b6cca5889e667193c7e794186db73c2000 (patch)
tree10f6a612d97b3ab5ba4ecd75b6decb669f178d76 /net/dccp
parent6bb3ce25d05f2990c8a19adaf427531430267c1f (diff)
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>
Diffstat (limited to 'net/dccp')
-rw-r--r--net/dccp/feat.c19
-rw-r--r--net/dccp/options.c18
-rw-r--r--net/dccp/timer.c12
3 files changed, 8 insertions, 41 deletions
diff --git a/net/dccp/feat.c b/net/dccp/feat.c
index 069d8ffe4c6f..0e789e2e0aa9 100644
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -6,6 +6,8 @@
6 * 6 *
7 * ASSUMPTIONS 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 * o All currently known SP features have 1-byte quantities. If in the future 11 * o All currently known SP features have 1-byte quantities. If in the future
10 * extensions of RFCs 4340..42 define features with item lengths larger than 12 * extensions of RFCs 4340..42 define features with item lengths larger than
11 * one byte, a feature-specific extension of the code will be required. 13 * one byte, a feature-specific extension of the code will be required.
@@ -542,6 +544,9 @@ int dccp_feat_change_recv(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
542{ 544{
543 int rc; 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 dccp_feat_debug(type, feature, *val); 550 dccp_feat_debug(type, feature, *val);
546 551
547 /* figure out if it's SP or NN feature */ 552 /* figure out if it's SP or NN feature */
@@ -591,6 +596,9 @@ int dccp_feat_confirm_recv(struct sock *sk, u8 type, u8 feature,
591 int found = 0; 596 int found = 0;
592 int all_confirmed = 1; 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 dccp_feat_debug(type, feature, *val); 602 dccp_feat_debug(type, feature, *val);
595 603
596 /* locate our change request */ 604 /* locate our change request */
@@ -625,17 +633,6 @@ int dccp_feat_confirm_recv(struct sock *sk, u8 type, u8 feature,
625 all_confirmed = 0; 633 all_confirmed = 0;
626 } 634 }
627 635
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 }
638
639 if (!found) 636 if (!found)
640 dccp_pr_debug("%s(%d, ...) never requested\n", 637 dccp_pr_debug("%s(%d, ...) never requested\n",
641 dccp_feat_typename(type), feature); 638 dccp_feat_typename(type), feature);
diff --git a/net/dccp/options.c b/net/dccp/options.c
index 0809b63cb055..67a171a1268c 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -489,7 +489,6 @@ static int dccp_insert_feat_opt(struct sk_buff *skb, u8 type, u8 feat,
489 489
490static int dccp_insert_options_feat(struct sock *sk, struct sk_buff *skb) 490static int dccp_insert_options_feat(struct sock *sk, struct sk_buff *skb)
491{ 491{
492 struct dccp_sock *dp = dccp_sk(sk);
493 struct dccp_minisock *dmsk = dccp_msk(sk); 492 struct dccp_minisock *dmsk = dccp_msk(sk);
494 struct dccp_opt_pend *opt, *next; 493 struct dccp_opt_pend *opt, *next;
495 int change = 0; 494 int change = 0;
@@ -530,23 +529,6 @@ static int dccp_insert_options_feat(struct sock *sk, struct sk_buff *skb)
530 } 529 }
531 } 530 }
532 531
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 }
549
550 return 0; 532 return 0;
551} 533}
552 534
diff --git a/net/dccp/timer.c b/net/dccp/timer.c
index 54b3c7e9e016..162d1e683c39 100644
--- a/net/dccp/timer.c
+++ b/net/dccp/timer.c
@@ -87,17 +87,6 @@ static void dccp_retransmit_timer(struct sock *sk)
87{ 87{
88 struct inet_connection_sock *icsk = inet_csk(sk); 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 * More than than 4MSL (8 minutes) has passed, a RESET(aborted) was 91 * More than than 4MSL (8 minutes) has passed, a RESET(aborted) was
103 * sent, no need to retransmit, this sock is dead. 92 * sent, no need to retransmit, this sock is dead.
@@ -126,7 +115,6 @@ static void dccp_retransmit_timer(struct sock *sk)
126 return; 115 return;
127 } 116 }
128 117
129backoff:
130 icsk->icsk_backoff++; 118 icsk->icsk_backoff++;
131 119
132 icsk->icsk_rto = min(icsk->icsk_rto << 1, DCCP_RTO_MAX); 120 icsk->icsk_rto = min(icsk->icsk_rto << 1, DCCP_RTO_MAX);