]> err.no Git - linux-2.6/blobdiff - net/dccp/input.c
Merge master.kernel.org:/home/rmk/linux-2.6-mmc
[linux-2.6] / net / dccp / input.c
index 5847cf454e2657119b0d3c9bd32790e68e372d7d..ef29cef1dafe238196224bd8aed79cc139a2c329 100644 (file)
@@ -31,14 +31,10 @@ 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);
+       sk_wake_async(sk, 1, POLL_HUP);
 }
 
 static void dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb)
@@ -54,13 +50,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)
@@ -141,10 +132,16 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
                                            "(P.ackno %s or LAWL(%llu) <= P.ackno(%llu) <= S.AWH(%llu), "
                                            "sending SYNC...\n",
                               dccp_packet_name(dh->dccph_type),
-                              lswl, DCCP_SKB_CB(skb)->dccpd_seq, dp->dccps_swh,
+                              (unsigned long long) lswl,
+                              (unsigned long long)
+                              DCCP_SKB_CB(skb)->dccpd_seq,
+                              (unsigned long long) dp->dccps_swh,
                               (DCCP_SKB_CB(skb)->dccpd_ack_seq ==
                                DCCP_PKT_WITHOUT_ACK_SEQ) ? "doesn't exist" : "exists",
-                              lawl, DCCP_SKB_CB(skb)->dccpd_ack_seq, dp->dccps_awh);
+                              (unsigned long long) lawl,
+                              (unsigned long long)
+                              DCCP_SKB_CB(skb)->dccpd_ack_seq,
+                              (unsigned long long) dp->dccps_awh);
                dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, DCCP_PKT_SYNC);
                return -1;
        }
@@ -556,6 +553,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) {