Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 438adcaf authored by Parthasarathy Bhuvaragan's avatar Parthasarathy Bhuvaragan Committed by David S. Miller
Browse files

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: default avatarParthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8ea642ee
Loading
Loading
Loading
Loading
+43 −54
Original line number Diff line number Diff line
@@ -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;