aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2008-09-04 01:30:19 -0400
committerGerrit Renker <gerrit@erg.abdn.ac.uk>2008-09-04 01:45:27 -0400
commit5591d286281fdfb57914f5fad3ca001d44ce8fc6 (patch)
treee823aa756d48f31670815be0d4a1d1813d0d54d2
parent702083839b607f390dbed5d2304eb8fc5f4c85ac (diff)
dccp: Limit feature negotiation to connection setup phase
This patch starts the new implementation of feature negotiation: 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>
-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 faade82856fe..77ce2f6b0319 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.
@@ -652,6 +654,9 @@ int dccp_feat_change_recv(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
652{ 654{
653 int rc; 655 int rc;
654 656
657 /* Ignore Change requests other than during connection setup */
658 if (sk->sk_state != DCCP_LISTEN && sk->sk_state != DCCP_REQUESTING)
659 return 0;
655 dccp_feat_debug(type, feature, *val); 660 dccp_feat_debug(type, feature, *val);
656 661
657 /* figure out if it's SP or NN feature */ 662 /* figure out if it's SP or NN feature */
@@ -701,6 +706,9 @@ int dccp_feat_confirm_recv(struct sock *sk, u8 type, u8 feature,
701 int found = 0; 706 int found = 0;
702 int all_confirmed = 1; 707 int all_confirmed = 1;
703 708
709 /* Ignore Confirm options other than during connection setup */
710 if (sk->sk_state != DCCP_LISTEN && sk->sk_state != DCCP_REQUESTING)
711 return 0;
704 dccp_feat_debug(type, feature, *val); 712 dccp_feat_debug(type, feature, *val);
705 713
706 /* locate our change request */ 714 /* locate our change request */
@@ -735,17 +743,6 @@ int dccp_feat_confirm_recv(struct sock *sk, u8 type, u8 feature,
735 all_confirmed = 0; 743 all_confirmed = 0;
736 } 744 }
737 745
738 /* fix re-transmit timer */
739 /* XXX gotta make sure that no option negotiation occurs during
740 * connection shutdown. Consider that the CLOSEREQ is sent and timer is
741 * on. if all options are confirmed it might kill timer which should
742 * remain alive until close is received.
743 */
744 if (all_confirmed) {
745 dccp_pr_debug("clear feat negotiation timer %p\n", sk);
746 inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS);
747 }
748
749 if (!found) 746 if (!found)
750 dccp_pr_debug("%s(%d, ...) never requested\n", 747 dccp_pr_debug("%s(%d, ...) never requested\n",
751 dccp_feat_typename(type), feature); 748 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);