aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);