From: Jon M. <jm...@re...> - 2021-07-22 00:56:45
|
On 10/07/2021 12:46, Xin Long wrote: > For implicit-connect, when it's either SYN- or SYN+, an ACK should > be sent back to the client immediately. It's not appropriate for > the client to enter established state only after receiving data > from the server. > > On client side, after the SYN is sent out, tipc_wait_for_connect() > should be called to wait for the ACK if timeout is set. > > This patch also restricts __tipc_sendstream() to call __sendmsg() > only when it's in TIPC_OPEN state, so that the client can program > in a single loop doing both connecting and data sending like: > > for (...) > sendmsg(dest, buf); > > This makes the implicit-connect more implicit. > > Fixes: b97bf3fd8f6a ("[TIPC] Initial merge") > Signed-off-by: Xin Long <luc...@gm...> > --- > net/tipc/socket.c | 21 +++++++++++++-------- > 1 file changed, 13 insertions(+), 8 deletions(-) > > diff --git a/net/tipc/socket.c b/net/tipc/socket.c > index 34a97ea36cc8..ebd300c26a44 100644 > --- a/net/tipc/socket.c > +++ b/net/tipc/socket.c > @@ -158,6 +158,7 @@ static void tipc_sk_remove(struct tipc_sock *tsk); > static int __tipc_sendstream(struct socket *sock, struct msghdr *m, size_t dsz); > static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz); > static void tipc_sk_push_backlog(struct tipc_sock *tsk, bool nagle_ack); > +static int tipc_wait_for_connect(struct socket *sock, long *timeo_p); > > static const struct proto_ops packet_ops; > static const struct proto_ops stream_ops; > @@ -1515,8 +1516,13 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen) > rc = 0; > } > > - if (unlikely(syn && !rc)) > + if (unlikely(syn && !rc)) { > tipc_set_sk_state(sk, TIPC_CONNECTING); > + if (timeout) { > + timeout = msecs_to_jiffies(timeout); > + tipc_wait_for_connect(sock, &timeout); > + } > + } > > return rc ? rc : dlen; > } > @@ -1564,7 +1570,7 @@ static int __tipc_sendstream(struct socket *sock, struct msghdr *m, size_t dlen) > return -EMSGSIZE; > > /* Handle implicit connection setup */ > - if (unlikely(dest)) { > + if (unlikely(dest && sk->sk_state == TIPC_OPEN)) { > rc = __tipc_sendmsg(sock, m, dlen); > if (dlen && dlen == rc) { > tsk->peer_caps = tipc_node_get_capabilities(net, dnode); > @@ -2689,9 +2695,10 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags, > bool kern) > { > struct sock *new_sk, *sk = sock->sk; > - struct sk_buff *buf; > struct tipc_sock *new_tsock; > + struct msghdr m = {NULL,}; > struct tipc_msg *msg; > + struct sk_buff *buf; > long timeo; > int res; > > @@ -2737,19 +2744,17 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags, > } > > /* > - * Respond to 'SYN-' by discarding it & returning 'ACK'-. > - * Respond to 'SYN+' by queuing it on new socket. > + * Respond to 'SYN-' by discarding it & returning 'ACK'. > + * Respond to 'SYN+' by queuing it on new socket & returning 'ACK'. > */ > if (!msg_data_sz(msg)) { > - struct msghdr m = {NULL,}; > - > tsk_advance_rx_queue(sk); > - __tipc_sendstream(new_sock, &m, 0); > } else { > __skb_dequeue(&sk->sk_receive_queue); > __skb_queue_head(&new_sk->sk_receive_queue, buf); > skb_set_owner_r(buf, new_sk); > } > + __tipc_sendstream(new_sock, &m, 0); > release_sock(new_sk); > exit: > release_sock(sk); > Acked by: Jon Maloy <jm...@re...> |