diff options
Diffstat (limited to 'net/dccp/input.c')
-rw-r--r-- | net/dccp/input.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/net/dccp/input.c b/net/dccp/input.c index decf2f21149b..dacd4fd3c63c 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c | |||
@@ -22,16 +22,27 @@ | |||
22 | /* rate-limit for syncs in reply to sequence-invalid packets; RFC 4340, 7.5.4 */ | 22 | /* rate-limit for syncs in reply to sequence-invalid packets; RFC 4340, 7.5.4 */ |
23 | int sysctl_dccp_sync_ratelimit __read_mostly = HZ / 8; | 23 | int sysctl_dccp_sync_ratelimit __read_mostly = HZ / 8; |
24 | 24 | ||
25 | static void dccp_fin(struct sock *sk, struct sk_buff *skb) | 25 | static void dccp_enqueue_skb(struct sock *sk, struct sk_buff *skb) |
26 | { | 26 | { |
27 | sk->sk_shutdown |= RCV_SHUTDOWN; | ||
28 | sock_set_flag(sk, SOCK_DONE); | ||
29 | __skb_pull(skb, dccp_hdr(skb)->dccph_doff * 4); | 27 | __skb_pull(skb, dccp_hdr(skb)->dccph_doff * 4); |
30 | __skb_queue_tail(&sk->sk_receive_queue, skb); | 28 | __skb_queue_tail(&sk->sk_receive_queue, skb); |
31 | skb_set_owner_r(skb, sk); | 29 | skb_set_owner_r(skb, sk); |
32 | sk->sk_data_ready(sk, 0); | 30 | sk->sk_data_ready(sk, 0); |
33 | } | 31 | } |
34 | 32 | ||
33 | static void dccp_fin(struct sock *sk, struct sk_buff *skb) | ||
34 | { | ||
35 | /* | ||
36 | * On receiving Close/CloseReq, both RD/WR shutdown are performed. | ||
37 | * RFC 4340, 8.3 says that we MAY send further Data/DataAcks after | ||
38 | * receiving the closing segment, but there is no guarantee that such | ||
39 | * data will be processed at all. | ||
40 | */ | ||
41 | sk->sk_shutdown = SHUTDOWN_MASK; | ||
42 | sock_set_flag(sk, SOCK_DONE); | ||
43 | dccp_enqueue_skb(sk, skb); | ||
44 | } | ||
45 | |||
35 | static int dccp_rcv_close(struct sock *sk, struct sk_buff *skb) | 46 | static int dccp_rcv_close(struct sock *sk, struct sk_buff *skb) |
36 | { | 47 | { |
37 | int queued = 0; | 48 | int queued = 0; |
@@ -282,10 +293,7 @@ static int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb, | |||
282 | * - sk_shutdown == RCV_SHUTDOWN, use Code 1, "Not Listening" | 293 | * - sk_shutdown == RCV_SHUTDOWN, use Code 1, "Not Listening" |
283 | * - sk_receive_queue is full, use Code 2, "Receive Buffer" | 294 | * - sk_receive_queue is full, use Code 2, "Receive Buffer" |
284 | */ | 295 | */ |
285 | __skb_pull(skb, dh->dccph_doff * 4); | 296 | dccp_enqueue_skb(sk, skb); |
286 | __skb_queue_tail(&sk->sk_receive_queue, skb); | ||
287 | skb_set_owner_r(skb, sk); | ||
288 | sk->sk_data_ready(sk, 0); | ||
289 | return 0; | 297 | return 0; |
290 | case DCCP_PKT_ACK: | 298 | case DCCP_PKT_ACK: |
291 | goto discard; | 299 | goto discard; |