diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/dccp/feat.c | 19 | ||||
-rw-r--r-- | net/dccp/options.c | 18 | ||||
-rw-r--r-- | net/dccp/timer.c | 12 |
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 | ||
490 | static int dccp_insert_options_feat(struct sock *sk, struct sk_buff *skb) | 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 | 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 | ||
129 | backoff: | ||
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); |