tipc: refactor function tipc_sk_filter_connect()
authorJon Maloy <jon.maloy@ericsson.com>
Fri, 28 Sep 2018 18:23:20 +0000 (20:23 +0200)
committerDavid S. Miller <davem@davemloft.net>
Sat, 29 Sep 2018 18:24:22 +0000 (11:24 -0700)
We refactor the function tipc_sk_filter_connect(), both to make it
more readable and as a preparation for the next commit.

Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/tipc/socket.c

index 8152a813542290d33891e6ae05b6faf9b6395c61..094cfdc1e2b6e0f6caa3370c3d347e23af994bda 100644 (file)
@@ -1959,91 +1959,76 @@ static void tipc_sk_proto_rcv(struct sock *sk,
 }
 
 /**
- * tipc_filter_connect - Handle incoming message for a connection-based socket
+ * tipc_sk_filter_connect - check incoming message for a connection-based socket
  * @tsk: TIPC socket
- * @skb: pointer to message buffer. Set to NULL if buffer is consumed
- *
- * Returns true if everything ok, false otherwise
+ * @skb: pointer to message buffer.
+ * Returns true if message should be added to receive queue, false otherwise
  */
 static bool tipc_sk_filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
 {
        struct sock *sk = &tsk->sk;
        struct net *net = sock_net(sk);
        struct tipc_msg *hdr = buf_msg(skb);
-       u32 pport = msg_origport(hdr);
-       u32 pnode = msg_orignode(hdr);
+       bool con_msg = msg_connected(hdr);
+       u32 pport = tsk_peer_port(tsk);
+       u32 pnode = tsk_peer_node(tsk);
+       u32 oport = msg_origport(hdr);
+       u32 onode = msg_orignode(hdr);
+       int err = msg_errcode(hdr);
 
        if (unlikely(msg_mcast(hdr)))
                return false;
 
        switch (sk->sk_state) {
        case TIPC_CONNECTING:
-               /* Accept only ACK or NACK message */
-               if (unlikely(!msg_connected(hdr))) {
-                       if (pport != tsk_peer_port(tsk) ||
-                           pnode != tsk_peer_node(tsk))
-                               return false;
-
-                       tipc_set_sk_state(sk, TIPC_DISCONNECTING);
-                       sk->sk_err = ECONNREFUSED;
-                       sk->sk_state_change(sk);
-                       return true;
-               }
-
-               if (unlikely(msg_errcode(hdr))) {
-                       tipc_set_sk_state(sk, TIPC_DISCONNECTING);
-                       sk->sk_err = ECONNREFUSED;
-                       sk->sk_state_change(sk);
-                       return true;
-               }
-
-               if (unlikely(!msg_isdata(hdr))) {
-                       tipc_set_sk_state(sk, TIPC_DISCONNECTING);
-                       sk->sk_err = EINVAL;
-                       sk->sk_state_change(sk);
-                       return true;
+               /* Setup ACK */
+               if (likely(con_msg)) {
+                       if (err)
+                               break;
+                       tipc_sk_finish_conn(tsk, oport, onode);
+                       msg_set_importance(&tsk->phdr, msg_importance(hdr));
+                       /* ACK+ message with data is added to receive queue */
+                       if (msg_data_sz(hdr))
+                               return true;
+                       /* Empty ACK-, - wake up sleeping connect() and drop */
+                       sk->sk_data_ready(sk);
+                       msg_set_dest_droppable(hdr, 1);
+                       return false;
                }
+               /* Ignore connectionless message if not from listening socket */
+               if (oport != pport || onode != pnode)
+                       return false;
 
-               tipc_sk_finish_conn(tsk, msg_origport(hdr), msg_orignode(hdr));
-               msg_set_importance(&tsk->phdr, msg_importance(hdr));
-
-               /* If 'ACK+' message, add to socket receive queue */
-               if (msg_data_sz(hdr))
-                       return true;
-
-               /* If empty 'ACK-' message, wake up sleeping connect() */
-               sk->sk_data_ready(sk);
-
-               /* 'ACK-' message is neither accepted nor rejected: */
-               msg_set_dest_droppable(hdr, 1);
-               return false;
-
+               /* Rejected SYN - abort */
+               break;
        case TIPC_OPEN:
        case TIPC_DISCONNECTING:
-               break;
+               return false;
        case TIPC_LISTEN:
                /* Accept only SYN message */
-               if (!msg_connected(hdr) && !(msg_errcode(hdr)))
+               if (!con_msg && !err)
                        return true;
-               break;
+               return false;
        case TIPC_ESTABLISHED:
                /* Accept only connection-based messages sent by peer */
-               if (unlikely(!tsk_peer_msg(tsk, hdr)))
+               if (likely(con_msg && !err && pport == oport && pnode == onode))
+                       return true;
+               if (!tsk_peer_msg(tsk, hdr))
                        return false;
-
-               if (unlikely(msg_errcode(hdr))) {
-                       tipc_set_sk_state(sk, TIPC_DISCONNECTING);
-                       /* Let timer expire on it's own */
-                       tipc_node_remove_conn(net, tsk_peer_node(tsk),
-                                             tsk->portid);
-                       sk->sk_state_change(sk);
-               }
+               if (!err)
+                       return true;
+               tipc_set_sk_state(sk, TIPC_DISCONNECTING);
+               tipc_node_remove_conn(net, pnode, tsk->portid);
+               sk->sk_state_change(sk);
                return true;
        default:
                pr_err("Unknown sk_state %u\n", sk->sk_state);
        }
-
-       return false;
+       /* Abort connection setup attempt */
+       tipc_set_sk_state(sk, TIPC_DISCONNECTING);
+       sk->sk_err = ECONNREFUSED;
+       sk->sk_state_change(sk);
+       return true;
 }
 
 /**