> -----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

Reply via email to