NFC: Keep socket alive until the DISC PDU is actually sent
authorThierry Escande <thierry.escande@linux.intel.com>
Tue, 4 Jun 2013 09:34:51 +0000 (11:34 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Fri, 14 Jun 2013 11:45:05 +0000 (13:45 +0200)
This patch keeps the socket alive and therefore does not remove
it from the sockets list in the local until the DISC PDU has been
actually sent. Otherwise we would reply with DM PDUs before sending
the DISC one.

Signed-off-by: Thierry Escande <thierry.escande@linux.intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
net/nfc/llcp.h
net/nfc/llcp_core.c
net/nfc/llcp_sock.c

index ac16ebe3069d552fa476ed7d3f112208d95bfc06..71f649e5ef495fd289f506dd1f8313d5dc54af35 100644 (file)
@@ -19,6 +19,7 @@
 
 enum llcp_state {
        LLCP_CONNECTED = 1, /* wait_for_packet() wants that */
+       LLCP_DISCONNECTING,
        LLCP_CLOSED,
        LLCP_BOUND,
        LLCP_LISTEN,
index 158bdbf668ccf91fb211f49107d6b770d2fe98e4..1c4c048e0a1b622cec68c09332bc3f6354e910e8 100644 (file)
@@ -730,6 +730,13 @@ static void nfc_llcp_tx_work(struct work_struct *work)
                                       DUMP_PREFIX_OFFSET, 16, 1,
                                       skb->data, skb->len, true);
 
+                       if (ptype == LLCP_PDU_DISC && sk != NULL &&
+                           sk->sk_state == LLCP_DISCONNECTING) {
+                               nfc_llcp_sock_unlink(&local->sockets, sk);
+                               sock_orphan(sk);
+                               sock_put(sk);
+                       }
+
                        if (ptype == LLCP_PDU_I)
                                copy_skb = skb_copy(skb, GFP_ATOMIC);
 
index 03fd3162cee569779d7c129cd26e9df8367ad501..47e7acfc0236952cbc9dc502df42c255a4232fae 100644 (file)
@@ -626,6 +626,13 @@ static int llcp_sock_release(struct socket *sock)
 
        release_sock(sk);
 
+       /* Keep this sock alive and therefore do not remove it from the sockets
+        * list until the DISC PDU has been actually sent. Otherwise we would
+        * reply with DM PDUs before sending the DISC one.
+        */
+       if (sk->sk_state == LLCP_DISCONNECTING)
+               return err;
+
        if (sock->type == SOCK_RAW)
                nfc_llcp_sock_unlink(&local->raw_sockets, sk);
        else