tipc: refactor function tipc_sk_filter_connect()

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>
This commit is contained in:
Jon Maloy 2018-09-28 20:23:20 +02:00 committed by David S. Miller
parent afe8792fec
commit 39fdc9c71f
1 changed files with 50 additions and 65 deletions

View 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;
/* 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;
}
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;
}
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;
case TIPC_OPEN:
case TIPC_DISCONNECTING:
break;
case TIPC_LISTEN:
/* Accept only SYN message */
if (!msg_connected(hdr) && !(msg_errcode(hdr)))
return true;
break;
case TIPC_ESTABLISHED:
/* Accept only connection-based messages sent by peer */
if (unlikely(!tsk_peer_msg(tsk, hdr)))
/* Ignore connectionless message if not from listening socket */
if (oport != pport || onode != pnode)
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);
}
/* Rejected SYN - abort */
break;
case TIPC_OPEN:
case TIPC_DISCONNECTING:
return false;
case TIPC_LISTEN:
/* Accept only SYN message */
if (!con_msg && !err)
return true;
return false;
case TIPC_ESTABLISHED:
/* Accept only connection-based messages sent by peer */
if (likely(con_msg && !err && pport == oport && pnode == onode))
return true;
if (!tsk_peer_msg(tsk, hdr))
return false;
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;
}
/**