From 438adcaf0df181fb6bf2afa917c741cc8c9241c3 Mon Sep 17 00:00:00 2001 From: Parthasarathy Bhuvaragan Date: Tue, 1 Nov 2016 14:02:45 +0100 Subject: [PATCH] tipc: create TIPC_OPEN as a new sk_state In this commit, we create a new tipc socket state TIPC_OPEN in sk_state. We primarily replace the SS_UNCONNECTED sock->state with TIPC_OPEN. Signed-off-by: Parthasarathy Bhuvaragan Signed-off-by: David S. Miller --- net/tipc/socket.c | 97 +++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 54 deletions(-) diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 9215e2144b6a..b14dd2549980 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -53,6 +53,7 @@ enum { TIPC_LISTEN = TCP_LISTEN, TIPC_ESTABLISHED = TCP_ESTABLISHED, + TIPC_OPEN = TCP_CLOSE, }; /** @@ -348,16 +349,21 @@ static bool tsk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg) static int tipc_set_sk_state(struct sock *sk, int state) { int oldstate = sk->sk_socket->state; + int oldsk_state = sk->sk_state; int res = -EINVAL; switch (state) { + case TIPC_OPEN: + res = 0; + break; case TIPC_LISTEN: - if (oldstate == SS_UNCONNECTED) + if (oldsk_state == TIPC_OPEN) res = 0; break; case TIPC_ESTABLISHED: if (oldstate == SS_CONNECTING || - oldstate == SS_UNCONNECTED) + oldstate == SS_UNCONNECTED || + oldsk_state == TIPC_OPEN) res = 0; break; } @@ -423,8 +429,8 @@ static int tipc_sk_create(struct net *net, struct socket *sock, /* Finish initializing socket data structures */ sock->ops = ops; - sock->state = SS_UNCONNECTED; sock_init_data(sock, sk); + tipc_set_sk_state(sk, TIPC_OPEN); if (tipc_sk_insert(tsk)) { pr_warn("Socket create failed; port number exhausted\n"); return -EINVAL; @@ -448,6 +454,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock, if (sock->type == SOCK_DGRAM) tsk_set_unreliable(tsk, true); } + return 0; } @@ -652,28 +659,6 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr, * exits. TCP and other protocols seem to rely on higher level poll routines * to handle any preventable race conditions, so TIPC will do the same ... * - * TIPC sets the returned events as follows: - * - * socket state flags set - * ------------ --------- - * unconnected no read flags - * POLLOUT if port is not congested - * - * connecting POLLIN/POLLRDNORM if ACK/NACK in rx queue - * no write flags - * - * connected POLLIN/POLLRDNORM if data in rx queue - * POLLOUT if port is not congested - * - * disconnecting POLLIN/POLLRDNORM/POLLHUP - * no write flags - * - * listening POLLIN if SYN in rx queue - * no write flags - * - * ready POLLIN/POLLRDNORM if data in rx queue - * [connectionless] POLLOUT (since port cannot be congested) - * * IMPORTANT: The fact that a read or write operation is indicated does NOT * imply that the operation will succeed, merely that it should be performed * and will not block. @@ -687,27 +672,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock, sock_poll_wait(file, sk_sleep(sk), wait); - if (tipc_sk_type_connectionless(sk)) { - if (!tsk->link_cong) - mask |= POLLOUT; - if (!skb_queue_empty(&sk->sk_receive_queue)) - mask |= (POLLIN | POLLRDNORM); - return mask; - } - switch ((int)sock->state) { - case SS_UNCONNECTED: - switch (sk->sk_state) { - case TIPC_LISTEN: - if (!skb_queue_empty(&sk->sk_receive_queue)) - mask |= (POLLIN | POLLRDNORM); - break; - default: - if (!tsk->link_cong) - mask |= POLLOUT; - break; - } - break; case SS_CONNECTED: if (!tsk->link_cong && !tsk_conn_cong(tsk)) mask |= POLLOUT; @@ -719,6 +684,20 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock, case SS_DISCONNECTING: mask = (POLLIN | POLLRDNORM | POLLHUP); break; + default: + switch (sk->sk_state) { + case TIPC_OPEN: + if (!tsk->link_cong) + mask |= POLLOUT; + if (tipc_sk_type_connectionless(sk) && + (!skb_queue_empty(&sk->sk_receive_queue))) + mask |= (POLLIN | POLLRDNORM); + break; + case TIPC_LISTEN: + if (!skb_queue_empty(&sk->sk_receive_queue)) + mask |= (POLLIN | POLLRDNORM); + break; + } } return mask; @@ -965,7 +944,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz) if (!is_connectionless) { if (sk->sk_state == TIPC_LISTEN) return -EPIPE; - if (sock->state != SS_UNCONNECTED) + if (sk->sk_state != TIPC_OPEN) return -EISCONN; if (tsk->published) return -EOPNOTSUPP; @@ -1400,7 +1379,7 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m, size_t buf_len, lock_sock(sk); - if (!is_connectionless && unlikely(sock->state == SS_UNCONNECTED)) { + if (!is_connectionless && unlikely(sk->sk_state == TIPC_OPEN)) { res = -ENOTCONN; goto exit; } @@ -1497,7 +1476,7 @@ static int tipc_recv_stream(struct socket *sock, struct msghdr *m, lock_sock(sk); - if (unlikely(sock->state == SS_UNCONNECTED)) { + if (unlikely(sk->sk_state == TIPC_OPEN)) { res = -ENOTCONN; goto exit; } @@ -1689,17 +1668,22 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb) msg_set_dest_droppable(hdr, 1); return false; - case SS_UNCONNECTED: + case SS_DISCONNECTING: + break; + } + switch (sk->sk_state) { + case TIPC_OPEN: + break; + case TIPC_LISTEN: /* Accept only SYN message */ if (!msg_connected(hdr) && !(msg_errcode(hdr))) return true; break; - case SS_DISCONNECTING: - break; default: - pr_err("Unknown socket state %u\n", sock->state); + pr_err("Unknown sk_state %u\n", sk->sk_state); } + return false; } @@ -2008,8 +1992,9 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest, } previous = sock->state; - switch (sock->state) { - case SS_UNCONNECTED: + + switch (sk->sk_state) { + case TIPC_OPEN: /* Send a 'SYN-' to destination */ m.msg_name = dest; m.msg_namelen = destlen; @@ -2029,6 +2014,10 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest, * case is EINPROGRESS, rather than EALREADY. */ res = -EINPROGRESS; + break; + } + + switch (sock->state) { case SS_CONNECTING: if (previous == SS_CONNECTING) res = -EALREADY; -- GitLab