> -----Original Message-----
> From: Parthasarathy Bhuvaragan
> Sent: Thursday, April 27, 2017 07:54 AM
> To: [email protected]; Jon Maloy
> <[email protected]>; Ying Xue <[email protected]>
> Subject: [PATCH net v1 1/6] tipc: queue socket protocol error messages into
> socket receive buffer
>
> In filter_rcv(), when we detect protocol messages with error we reset the
> connection and notify the socket using sk_state_change().
> tipc_backlog_rcv() also calls filter_rcv() while holding the socket lock and
> since the socket is already awake sk_state_change() is ignored and this error
> is lost. Now the receive queue will remain empty and the socket sleeps
> forever.
>
> In this commit, we enqueue this error message into the socket's receive
> queue in addition to the above state change to cover all conditions.
>
> Signed-off-by: Parthasarathy Bhuvaragan
> <[email protected]>
> ---
> net/tipc/socket.c | 47 +++++++++++++++++++++++++----------------------
> 1 file changed, 25 insertions(+), 22 deletions(-)
>
> diff --git a/net/tipc/socket.c b/net/tipc/socket.c index
> 953655cc05a7..0ab98ec94e7e 100644
> --- a/net/tipc/socket.c
> +++ b/net/tipc/socket.c
> @@ -852,8 +852,10 @@ void tipc_sk_mcast_rcv(struct net *net, struct
> sk_buff_head *arrvq,
> * tipc_sk_proto_rcv - receive a connection mng protocol message
> * @tsk: receiving socket
> * @skb: pointer to message buffer.
> + *
> + * Returns true if skb should be queued to socket, false otherwise.
> */
> -static void tipc_sk_proto_rcv(struct tipc_sock *tsk, struct sk_buff *skb,
> +static bool tipc_sk_proto_rcv(struct tipc_sock *tsk, struct sk_buff
> +*skb,
> struct sk_buff_head *xmitq)
> {
> struct sock *sk = &tsk->sk;
> @@ -871,7 +873,7 @@ static void tipc_sk_proto_rcv(struct tipc_sock *tsk,
> struct sk_buff *skb,
> tipc_node_remove_conn(sock_net(sk), tsk_peer_node(tsk),
> tsk_peer_port(tsk));
> sk->sk_state_change(sk);
> - goto exit;
Here you could convert the message into an empty user data message (LOW,
CONNECTED, no error code) before you return it, just to emphasize that we never
add non-data messages to the receive queue.
Along with a comment saying so, this will make it clearer how it is dropped in
tipc_recv_stream()/tipc_recvmsg()
///jon
> + return true;
> }
>
> tsk->probe_unacked = false;
> @@ -880,7 +882,7 @@ static void tipc_sk_proto_rcv(struct tipc_sock *tsk,
> struct sk_buff *skb,
> msg_set_type(hdr, CONN_PROBE_REPLY);
> if (tipc_msg_reverse(onode, &skb, TIPC_OK))
> __skb_queue_tail(xmitq, skb);
> - return;
> + return false;
> } else if (mtyp == CONN_ACK) {
> conn_cong = tsk_conn_cong(tsk);
> tsk->snt_unacked -= msg_conn_ack(hdr); @@ -893,6 +895,7
> @@ static void tipc_sk_proto_rcv(struct tipc_sock *tsk, struct sk_buff *skb,
> }
> exit:
> kfree_skb(skb);
> + return false;
> }
>
> /**
> @@ -1699,35 +1702,35 @@ static bool filter_rcv(struct sock *sk, struct
> sk_buff *skb,
> int usr = msg_user(hdr);
> u32 onode;
>
> - if (unlikely(msg_user(hdr) == CONN_MANAGER)) {
> - tipc_sk_proto_rcv(tsk, skb, xmitq);
> - return false;
> - }
> -
> - if (unlikely(usr == SOCK_WAKEUP)) {
> + switch (usr) {
> + case CONN_MANAGER:
> + if (!tipc_sk_proto_rcv(tsk, skb, xmitq))
> + return false;
> + break;
> + case SOCK_WAKEUP:
> onode = msg_orignode(hdr);
> kfree_skb(skb);
> u32_del(&tsk->cong_links, onode);
> tsk->cong_link_cnt--;
> sk->sk_write_space(sk);
> return false;
> - }
> -
> - /* Drop if illegal message type */
> - if (unlikely(msg_type(hdr) > TIPC_DIRECT_MSG)) {
> - kfree_skb(skb);
> - return false;
> - }
> + default:
> + /* Drop if illegal message type */
> + if (unlikely(msg_type(hdr) > TIPC_DIRECT_MSG)) {
> + kfree_skb(skb);
> + return false;
> + }
>
> - /* Reject if wrong message type for current socket state */
> - if (tipc_sk_type_connectionless(sk)) {
> - if (msg_connected(hdr)) {
> + /* Reject if wrong message type for current socket state */
> + if (tipc_sk_type_connectionless(sk)) {
> + if (msg_connected(hdr)) {
> + err = TIPC_ERR_NO_PORT;
> + goto reject;
> + }
> + } else if (unlikely(!filter_connect(tsk, skb))) {
> err = TIPC_ERR_NO_PORT;
> goto reject;
> }
> - } else if (unlikely(!filter_connect(tsk, skb))) {
> - err = TIPC_ERR_NO_PORT;
> - goto reject;
> }
>
> /* Reject message if there isn't room to queue it */
> --
> 2.1.4
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
tipc-discussion mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tipc-discussion