> -----Original Message----- > From: Parthasarathy Bhuvaragan > Sent: Monday, March 20, 2017 05:10 AM > To: tipc-discussion@lists.sourceforge.net; Jon Maloy > <jon.ma...@ericsson.com>; Ying Xue <ying....@windriver.com> > Subject: [PATCH net v1 5/7] tipc: improve error validations for sockets in > CONNECTING state > > Until now, the checks for sockets in CONNECTING state was based on the > assumption that the incoming message was always from the peer's accepted > data socket. > > However an application using a non-blocking socket sends an implicit > connect, this socket which is in CONNECTING state can receive error > messages from the peer's listening socket. As we discard these messages, > the application socket hangs as there due to inactivity. > In addition to this, there are other places where we process errors but do not > notify the user. > > In this commit, we process such incoming error messages and notify out s/out/our ///jon
> users about them using sk_state_change(). > > Signed-off-by: Parthasarathy Bhuvaragan > <parthasarathy.bhuvara...@ericsson.com> > --- > net/tipc/socket.c | 25 ++++++++++++++++++++++--- > 1 file changed, 22 insertions(+), 3 deletions(-) > > diff --git a/net/tipc/socket.c b/net/tipc/socket.c index > cb8d2dd2b10c..1f18b435f915 100644 > --- a/net/tipc/socket.c > +++ b/net/tipc/socket.c > @@ -1262,7 +1262,10 @@ static int tipc_wait_for_rcvmsg(struct socket > *sock, long *timeop) > struct sock *sk = sock->sk; > DEFINE_WAIT(wait); > long timeo = *timeop; > - int err; > + int err = sock_error(sk); > + > + if (err) > + return err; > > for (;;) { > prepare_to_wait(sk_sleep(sk), &wait, > TASK_INTERRUPTIBLE); @@ -1284,6 +1287,10 @@ static int > tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) > err = sock_intr_errno(timeo); > if (signal_pending(current)) > break; > + > + err = sock_error(sk); > + if (err) > + break; > } > finish_wait(sk_sleep(sk), &wait); > *timeop = timeo; > @@ -1554,6 +1561,8 @@ static bool 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); > > if (unlikely(msg_mcast(hdr))) > return false; > @@ -1561,18 +1570,28 @@ static bool filter_connect(struct tipc_sock *tsk, > struct sk_buff *skb) > switch (sk->sk_state) { > case TIPC_CONNECTING: > /* Accept only ACK or NACK message */ > - if (unlikely(!msg_connected(hdr))) > - return false; > + 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; > + } > > 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; > } > > -- > 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 tipc-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tipc-discussion