diff options
author | Arnaldo Carvalho de Melo <acme@mandriva.com> | 2005-08-24 04:50:06 (GMT) |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2005-08-29 23:04:31 (GMT) |
commit | 7ad07e7cf343181002c10c39d3f57a88e4903d4f (patch) | |
tree | c22067f3f443faebdcd3403fa8ce7c5c89662c60 /net/dccp/input.c | |
parent | 58e45131dc269eff0983c6d44494f9e687686900 (diff) | |
download | linux-7ad07e7cf343181002c10c39d3f57a88e4903d4f.tar.xz |
[DCCP]: Implement the CLOSING timer
So that we retransmit CLOSE/CLOSEREQ packets till they elicit an
answer or we hit a timeout.
Most of the machinery uses TCP approaches, this code has to be
polished & audited, but this is better than we had before.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dccp/input.c')
-rw-r--r-- | net/dccp/input.c | 26 |
1 files changed, 11 insertions, 15 deletions
diff --git a/net/dccp/input.c b/net/dccp/input.c index 8540253..02af05e 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c @@ -31,14 +31,9 @@ static void dccp_fin(struct sock *sk, struct sk_buff *skb) static void dccp_rcv_close(struct sock *sk, struct sk_buff *skb) { - switch (sk->sk_state) { - case DCCP_PARTOPEN: - case DCCP_OPEN: - dccp_v4_send_reset(sk, DCCP_RESET_CODE_CLOSED); - dccp_fin(sk, skb); - dccp_set_state(sk, DCCP_CLOSED); - break; - } + dccp_v4_send_reset(sk, DCCP_RESET_CODE_CLOSED); + dccp_fin(sk, skb); + dccp_set_state(sk, DCCP_CLOSED); } static void dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb) @@ -54,13 +49,8 @@ static void dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb) return; } - switch (sk->sk_state) { - case DCCP_PARTOPEN: - case DCCP_OPEN: - dccp_set_state(sk, DCCP_CLOSING); - dccp_send_close(sk); - break; - } + dccp_set_state(sk, DCCP_CLOSING); + dccp_send_close(sk, 0); } static inline void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb) @@ -562,6 +552,12 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, DCCP_PKT_SYNC); goto discard; + } else if (dh->dccph_type == DCCP_PKT_CLOSEREQ) { + dccp_rcv_closereq(sk, skb); + goto discard; + } else if (dh->dccph_type == DCCP_PKT_CLOSE) { + dccp_rcv_close(sk, skb); + return 0; } switch (sk->sk_state) { |