Commit d83bd95b authored by Gerrit Renker's avatar Gerrit Renker Committed by David S. Miller

[DCCP]: Check for unread data on close

This removes one FIXME with regard to close when there is still unread data.
The mechanism is implemented similar to TCP: with regard to DCCP-specifics,
a Reset with Code 2, "Aborted" is sent to the peer.

This corresponds in part to RFC 4340, 8.1.1 and 8.1.5.
Signed-off-by: default avatarGerrit Renker <gerrit@erg.abdn.ac.uk>
Signed-off-by: default avatarIan McDonald <ian.mcdonald@jandi.co.nz>
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent dcfbc7e9
......@@ -891,6 +891,7 @@ void dccp_close(struct sock *sk, long timeout)
{
struct dccp_sock *dp = dccp_sk(sk);
struct sk_buff *skb;
u32 data_was_unread = 0;
int state;
lock_sock(sk);
......@@ -913,12 +914,17 @@ void dccp_close(struct sock *sk, long timeout)
* descriptor close, not protocol-sourced closes, because the
*reader process may not have drained the data yet!
*/
/* FIXME: check for unread data */
while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) {
data_was_unread += skb->len;
__kfree_skb(skb);
}
if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) {
if (data_was_unread) {
/* Unread data was tossed, send an appropriate Reset Code */
DCCP_WARN("DCCP: ABORT -- %u bytes unread\n", data_was_unread);
dccp_send_reset(sk, DCCP_RESET_CODE_ABORTED);
dccp_set_state(sk, DCCP_CLOSED);
} else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) {
/* Check zero linger _after_ checking for unread data. */
sk->sk_prot->disconnect(sk, 0);
} else if (dccp_close_state(sk)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment