aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/proto.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp/proto.c')
-rw-r--r--net/dccp/proto.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index d48005f653c7..5f47b458ed8f 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -891,6 +891,7 @@ void dccp_close(struct sock *sk, long timeout)
891{ 891{
892 struct dccp_sock *dp = dccp_sk(sk); 892 struct dccp_sock *dp = dccp_sk(sk);
893 struct sk_buff *skb; 893 struct sk_buff *skb;
894 u32 data_was_unread = 0;
894 int state; 895 int state;
895 896
896 lock_sock(sk); 897 lock_sock(sk);
@@ -913,12 +914,17 @@ void dccp_close(struct sock *sk, long timeout)
913 * descriptor close, not protocol-sourced closes, because the 914 * descriptor close, not protocol-sourced closes, because the
914 *reader process may not have drained the data yet! 915 *reader process may not have drained the data yet!
915 */ 916 */
916 /* FIXME: check for unread data */
917 while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) { 917 while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) {
918 data_was_unread += skb->len;
918 __kfree_skb(skb); 919 __kfree_skb(skb);
919 } 920 }
920 921
921 if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { 922 if (data_was_unread) {
923 /* Unread data was tossed, send an appropriate Reset Code */
924 DCCP_WARN("DCCP: ABORT -- %u bytes unread\n", data_was_unread);
925 dccp_send_reset(sk, DCCP_RESET_CODE_ABORTED);
926 dccp_set_state(sk, DCCP_CLOSED);
927 } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) {
922 /* Check zero linger _after_ checking for unread data. */ 928 /* Check zero linger _after_ checking for unread data. */
923 sk->sk_prot->disconnect(sk, 0); 929 sk->sk_prot->disconnect(sk, 0);
924 } else if (dccp_close_state(sk)) { 930 } else if (dccp_close_state(sk)) {