[DCCP]: Perform SHUT_RD and SHUT_WR on receiving close
The first change is to close the write-end in addition to the read-end when
a fin-like segment (Close or CloseReq) is received by DCCP. This accounts
for the fact that DCCP, in contrast to TCP, does not have a half-close. I
checked the specification - when a fin-like segment has been sent there is
no guarantee at all that any further data will be processed.
Thus this patch performs SHUT_WR in addition to the SHUT_RD when a fin-like
segment is encountered.
The second change is minor; I noted that code appears twice in different
places and think it makes sense to put this into a self-contained function.
Signed-off-by: Gerrit Renker <[EMAIL PROTECTED]>
---
net/dccp/input.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -19,16 +19,27 @@
#include "ccid.h"
#include "dccp.h"
-static void dccp_fin(struct sock *sk, struct sk_buff *skb)
+static void dccp_enqueue_skb(struct sock *sk, struct sk_buff *skb)
{
- sk->sk_shutdown |= RCV_SHUTDOWN;
- sock_set_flag(sk, SOCK_DONE);
__skb_pull(skb, dccp_hdr(skb)->dccph_doff * 4);
__skb_queue_tail(&sk->sk_receive_queue, skb);
skb_set_owner_r(skb, sk);
sk->sk_data_ready(sk, 0);
}
+static void dccp_fin(struct sock *sk, struct sk_buff *skb)
+{
+ /*
+ * On receiving Close/CloseReq, both RD/WR shutdown are performed.
+ * RFC 4340, 8.3 says that we MAY send further Data/DataAcks after
+ * receiving the closing segment, but there is no guarantee that such
+ * data will be processed at all.
+ */
+ sk->sk_shutdown = SHUTDOWN_MASK;
+ sock_set_flag(sk, SOCK_DONE);
+ dccp_enqueue_skb(sk, skb);
+}
+
static void dccp_rcv_close(struct sock *sk, struct sk_buff *skb)
{
if (sk->sk_state == DCCP_CLOSEREQ) {
@@ -187,10 +198,7 @@ static int __dccp_rcv_established(struct
* FIXME: check if sk_receive_queue is full, schedule
DATA_DROPPED
* option if it is.
*/
- __skb_pull(skb, dh->dccph_doff * 4);
- __skb_queue_tail(&sk->sk_receive_queue, skb);
- skb_set_owner_r(skb, sk);
- sk->sk_data_ready(sk, 0);
+ dccp_enqueue_skb(sk, skb);
return 0;
case DCCP_PKT_ACK:
goto discard;
-
To unsubscribe from this list: send the line "unsubscribe dccp" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html