In this commit, we remove the state SS_CONNECTED and replace it
with the function tipc_sk_state_connected() wherever possible.
A socket with sk_state TIPC_ESTABLISHED or TIPC_PROBING replaces
the socket state SS_CONNECTED.

After these changes, the sock->state is no longer explicitly used by
tipc. The FSM below is for various types of connection oriented sockets.

Stream Server Listening Socket:
+------------------+        +-------------+
| TIPC_UNCONNECTED |------->| TIPC_LISTEN |
+------------------+        +-------------+
                                  |
+--------------------+            |
| TIPC_DISCONNECTING |<-----------+
+--------------------+

Stream Server Data Socket:
+-----------------+        +------------------+
|TIPC_UNCONNECTED |------> | TIPC_ESTABLISHED |<---+
+-----------------+        +------------------+    |
                               ^   |    |          |
                               |   |    +----------+
                               |   v
+------------------+      +-------------+
|TIPC_DISCONNECTING|<-----|TIPC_PROBING |
+------------------+      +-------------+

Stream Socket Client:
+-----------------+       +-----------------+
|TIPC_UNCONNECTED |------>| TIPC_CONNECTING |
+-----------------+       +-----------------+
                                  |
                                  |
                                  v
                          +------------------+
                          | TIPC_ESTABLISHED |<---+
                          +------------------+    |
                               ^   |    |         |
                               |   |    +---------+
                               |   v
+------------------+      +-------------+
|TIPC_DISCONNECTING|<-----|TIPC_PROBING |
+------------------+      +-------------+

Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvara...@ericsson.com>
---
 net/tipc/socket.c | 90 +++++++++++++++++++++++++------------------------------
 1 file changed, 41 insertions(+), 49 deletions(-)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index d2598186fb65..6128c1646866 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -286,7 +286,7 @@ static void tsk_rej_rx_queue(struct sock *sk)
 
 static bool tipc_sk_state_connected(struct sock *sk)
 {
-       return sk->sk_socket->state == SS_CONNECTED;
+       return sk->sk_state == TIPC_ESTABLISHED || sk->sk_state == TIPC_PROBING;
 }
 
 /* tipc_sk_type_connectionless - check if the socket is datagram socket
@@ -514,7 +514,7 @@ static int tipc_release(struct socket *sock)
                        kfree_skb(skb);
                else {
                        if ((sk->sk_state == TIPC_CONNECTING) ||
-                           (sock->state == SS_CONNECTED)) {
+                           tipc_sk_state_connected(sk)) {
                                tipc_set_state(sk, TIPC_DISCONNECTING);
                                tipc_node_remove_conn(net, dnode, tsk->portid);
                        }
@@ -628,7 +628,7 @@ static int tipc_getname(struct socket *sock, struct 
sockaddr *uaddr,
 
        memset(addr, 0, sizeof(*addr));
        if (peer) {
-               if ((sock->state != SS_CONNECTED) &&
+               if ((!tipc_sk_state_connected(sk)) &&
                    ((peer != 2) || (sk->sk_state != TIPC_DISCONNECTING)))
                        return -ENOTCONN;
                addr->addr.id.ref = tsk_peer_port(tsk);
@@ -704,28 +704,24 @@ static unsigned int tipc_poll(struct file *file, struct 
socket *sock,
                return mask;
        }
 
-       switch ((int)sock->state) {
-       case SS_CONNECTED:
+       switch (sk->sk_state) {
+       case TIPC_PROBING:
+       case TIPC_ESTABLISHED:
                if (!tsk->link_cong && !tsk_conn_cong(tsk))
                        mask |= POLLOUT;
+               /* fall thru' */
+       case TIPC_LISTEN:
+       case TIPC_CONNECTING:
                if (!skb_queue_empty(&sk->sk_receive_queue))
                        mask |= (POLLIN | POLLRDNORM);
                break;
-       default:
-               switch (sk->sk_state) {
-               case TIPC_UNCONNECTED:
-                       if (!tsk->link_cong)
-                               mask |= POLLOUT;
-                       break;
-               case TIPC_LISTEN:
-               case TIPC_CONNECTING:
-                       if (!skb_queue_empty(&sk->sk_receive_queue))
-                               mask |= (POLLIN | POLLRDNORM);
-                       break;
-               case TIPC_DISCONNECTING:
-                       mask = (POLLIN | POLLRDNORM | POLLHUP);
-                       break;
-               }
+       case TIPC_UNCONNECTED:
+               if (!tsk->link_cong)
+                       mask |= POLLOUT;
+               break;
+       case TIPC_DISCONNECTING:
+               mask = (POLLIN | POLLRDNORM | POLLHUP);
+               break;
        }
 
        return mask;
@@ -1056,7 +1052,7 @@ static int tipc_wait_for_sndpkt(struct socket *sock, long 
*timeo_p)
                        return err;
                if (sk->sk_state == TIPC_DISCONNECTING)
                        return -EPIPE;
-               else if (sock->state != SS_CONNECTED)
+               else if (!tipc_sk_state_connected(sk))
                        return -ENOTCONN;
                if (!*timeo_p)
                        return -EAGAIN;
@@ -1123,7 +1119,7 @@ static int __tipc_send_stream(struct socket *sock, struct 
msghdr *m, size_t dsz)
        if (dsz > (uint)INT_MAX)
                return -EMSGSIZE;
 
-       if (unlikely(sock->state != SS_CONNECTED)) {
+       if (unlikely(!tipc_sk_state_connected(sk))) {
                if (sk->sk_state == TIPC_DISCONNECTING)
                        return -EPIPE;
                else
@@ -1633,28 +1629,11 @@ static bool filter_connect(struct tipc_sock *tsk, 
struct sk_buff *skb)
 {
        struct sock *sk = &tsk->sk;
        struct net *net = sock_net(sk);
-       struct socket *sock = sk->sk_socket;
        struct tipc_msg *hdr = buf_msg(skb);
 
        if (unlikely(msg_mcast(hdr)))
                return false;
 
-       switch ((int)sock->state) {
-       case SS_CONNECTED:
-
-               /* Accept only connection-based messages sent by peer */
-               if (unlikely(!tsk_peer_msg(tsk, hdr)))
-                       return false;
-
-               if (unlikely(msg_errcode(hdr))) {
-                       tipc_set_state(sk, TIPC_DISCONNECTING);
-                       /* Let timer expire on it's own */
-                       tipc_node_remove_conn(net, tsk_peer_node(tsk),
-                                             tsk->portid);
-               }
-               return true;
-       }
-
        switch (sk->sk_state) {
        case TIPC_CONNECTING:
                /* Accept only ACK or NACK message */
@@ -1675,7 +1654,6 @@ static bool filter_connect(struct tipc_sock *tsk, struct 
sk_buff *skb)
 
                tipc_sk_finish_conn(tsk, msg_origport(hdr), msg_orignode(hdr));
                msg_set_importance(&tsk->phdr, msg_importance(hdr));
-               sock->state = SS_CONNECTED;
 
                /* If 'ACK+' message, add to socket receive queue */
                if (msg_data_sz(hdr))
@@ -1700,6 +1678,19 @@ static bool filter_connect(struct tipc_sock *tsk, struct 
sk_buff *skb)
                if (!msg_connected(hdr) && !(msg_errcode(hdr)))
                        return true;
                break;
+       case TIPC_PROBING:
+       case TIPC_ESTABLISHED:
+               /* Accept only connection-based messages sent by peer */
+               if (unlikely(!tsk_peer_msg(tsk, hdr)))
+                       return false;
+
+               if (unlikely(msg_errcode(hdr))) {
+                       tipc_set_state(sk, TIPC_DISCONNECTING);
+                       /* Let timer expire on it's own */
+                       tipc_node_remove_conn(net, tsk_peer_node(tsk),
+                                             tsk->portid);
+               }
+               return true;
        default:
                pr_err("Unknown sk_state %u\n", sk->sk_state);
        }
@@ -2045,13 +2036,14 @@ static int tipc_connect(struct socket *sock, struct 
sockaddr *dest,
                timeout = msecs_to_jiffies(timeout);
                /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */
                res = tipc_wait_for_connect(sock, &timeout);
-               goto exit;
-       }
-
-       if (sock->state == SS_CONNECTED)
+               break;
+       case TIPC_PROBING:
+       case TIPC_ESTABLISHED:
                res = -EISCONN;
-       else
+               break;
+       default:
                res = -EINVAL;
+       }
 
 exit:
        release_sock(sk);
@@ -2160,7 +2152,6 @@ static int tipc_accept(struct socket *sock, struct socket 
*new_sock, int flags)
 
        /* Connect new socket to it's peer */
        tipc_sk_finish_conn(new_tsock, msg_origport(msg), msg_orignode(msg));
-       new_sock->state = SS_CONNECTED;
 
        tsk_set_importance(new_tsock, msg_importance(msg));
        if (msg_named(msg)) {
@@ -2214,7 +2205,10 @@ static int tipc_shutdown(struct socket *sock, int how)
 
        lock_sock(sk);
 
-       if (sock->state == SS_CONNECTED || sk->sk_state == TIPC_CONNECTING) {
+       switch (sk->sk_state) {
+       case TIPC_PROBING:
+       case TIPC_CONNECTING:
+       case TIPC_ESTABLISHED:
 
 restart:
                dnode = tsk_peer_node(tsk);
@@ -2236,9 +2230,7 @@ restart:
                }
                tipc_set_state(sk, TIPC_DISCONNECTING);
                tipc_node_remove_conn(net, dnode, tsk->portid);
-       }
 
-       switch (sk->sk_state) {
        case TIPC_DISCONNECTING:
 
                /* Discard any unreceived messages */
-- 
2.1.4


------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are 
consuming the most bandwidth. Provides multi-vendor support for NetFlow, 
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports.http://sdm.link/zohodev2dev
_______________________________________________
tipc-discussion mailing list
tipc-discussion@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tipc-discussion

Reply via email to