Skip to content

Commit f74e91b

Browse files
Gerrit Renkerdavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 6bb3ce2 commit f74e91b

File tree

3 files changed

+8
-41
lines changed

3 files changed

+8
-41
lines changed

net/dccp/feat.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
*
77
* ASSUMPTIONS
88
* -----------
9+
* o Feature negotiation is coordinated with connection setup (as in TCP), wild
10+
* changes of parameters of an established connection are not supported.
911
* o All currently known SP features have 1-byte quantities. If in the future
1012
* extensions of RFCs 4340..42 define features with item lengths larger than
1113
* 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)
542544
{
543545
int rc;
544546

547+
/* Ignore Change requests other than during connection setup */
548+
if (sk->sk_state != DCCP_LISTEN && sk->sk_state != DCCP_REQUESTING)
549+
return 0;
545550
dccp_feat_debug(type, feature, *val);
546551

547552
/* 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,
591596
int found = 0;
592597
int all_confirmed = 1;
593598

599+
/* Ignore Confirm options other than during connection setup */
600+
if (sk->sk_state != DCCP_LISTEN && sk->sk_state != DCCP_REQUESTING)
601+
return 0;
594602
dccp_feat_debug(type, feature, *val);
595603

596604
/* locate our change request */
@@ -625,17 +633,6 @@ int dccp_feat_confirm_recv(struct sock *sk, u8 type, u8 feature,
625633
all_confirmed = 0;
626634
}
627635

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-
639636
if (!found)
640637
dccp_pr_debug("%s(%d, ...) never requested\n",
641638
dccp_feat_typename(type), feature);

net/dccp/options.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,6 @@ static int dccp_insert_feat_opt(struct sk_buff *skb, u8 type, u8 feat,
489489

490490
static int dccp_insert_options_feat(struct sock *sk, struct sk_buff *skb)
491491
{
492-
struct dccp_sock *dp = dccp_sk(sk);
493492
struct dccp_minisock *dmsk = dccp_msk(sk);
494493
struct dccp_opt_pend *opt, *next;
495494
int change = 0;
@@ -530,23 +529,6 @@ static int dccp_insert_options_feat(struct sock *sk, struct sk_buff *skb)
530529
}
531530
}
532531

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-
550532
return 0;
551533
}
552534

net/dccp/timer.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,6 @@ static void dccp_retransmit_timer(struct sock *sk)
8787
{
8888
struct inet_connection_sock *icsk = inet_csk(sk);
8989

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-
10190
/*
10291
* More than than 4MSL (8 minutes) has passed, a RESET(aborted) was
10392
* sent, no need to retransmit, this sock is dead.
@@ -126,7 +115,6 @@ static void dccp_retransmit_timer(struct sock *sk)
126115
return;
127116
}
128117

129-
backoff:
130118
icsk->icsk_backoff++;
131119

132120
icsk->icsk_rto = min(icsk->icsk_rto << 1, DCCP_RTO_MAX);

0 commit comments

Comments
 (0)