Acked-by: Jon

> -----Original Message-----
> From: Tuong Lien <tuong.t.l...@dektech.com.au>
> Sent: 30-Nov-19 05:19
> To: tipc-discussion@lists.sourceforge.net; Jon Maloy 
> <jon.ma...@ericsson.com>; ma...@donjonn.com;
> ying....@windriver.com
> Subject: [PATCH RFC] tipc: fix retrans failure due to wrong destination
> 
> When a user message is sent, TIPC will check if the socket has faced a
> congestion at link layer. If that happens, it will make a sleep to wait
> for the congestion to disappear. This leaves a gap for other users to
> take over the socket (e.g. multi threads) since the socket is released
> as well. Also, in case of connectionless (e.g. SOCK_RDM), user is free
> to send messages to various destinations (e.g. via 'sendto()'), then
> the socket's preformatted header has to be updated correspondingly
> prior to the actual payload message building.
> 
> Unfortunately, the latter action is done before the first action which
> causes a condition issue that the destination of a certain message can
> be modified incorrectly in the middle, leading to wrong destination
> when that message is built. Consequently, when the message is sent to
> the link layer, it gets stuck there forever because the peer node will
> simply reject it. After a number of retransmission attempts, the link
> is eventually taken down and the retransmission failure is reported.
> 
> This commit fixes the problem by rearranging the order of actions to
> prevent the race condition from occurring, so the message building is
> 'atomic' and its header will not be modified by anyone.
> 
> Fixes: 365ad353c256 ("tipc: reduce risk of user starvation during link 
> congestion")
> Signed-off-by: Tuong Lien <tuong.t.l...@dektech.com.au>
> ---
>  net/tipc/socket.c | 32 ++++++++++++++++++--------------
>  1 file changed, 18 insertions(+), 14 deletions(-)
> 
> diff --git a/net/tipc/socket.c b/net/tipc/socket.c
> index a1c8d722ca20..9b0280a562a4 100644
> --- a/net/tipc/socket.c
> +++ b/net/tipc/socket.c
> @@ -1361,8 +1361,8 @@ static int __tipc_sendmsg(struct socket *sock, struct 
> msghdr *m, size_t dlen)
>       struct tipc_msg *hdr = &tsk->phdr;
>       struct tipc_name_seq *seq;
>       struct sk_buff_head pkts;
> -     u32 dport, dnode = 0;
> -     u32 type, inst;
> +     u32 dport = 0, dnode = 0;
> +     u32 type = 0, inst = 0;
>       int mtu, rc;
> 
>       if (unlikely(dlen > TIPC_MAX_USER_MSG_SIZE))
> @@ -1415,23 +1415,11 @@ static int __tipc_sendmsg(struct socket *sock, struct 
> msghdr *m, size_t dlen)
>               type = dest->addr.name.name.type;
>               inst = dest->addr.name.name.instance;
>               dnode = dest->addr.name.domain;
> -             msg_set_type(hdr, TIPC_NAMED_MSG);
> -             msg_set_hdr_sz(hdr, NAMED_H_SIZE);
> -             msg_set_nametype(hdr, type);
> -             msg_set_nameinst(hdr, inst);
> -             msg_set_lookup_scope(hdr, tipc_node2scope(dnode));
>               dport = tipc_nametbl_translate(net, type, inst, &dnode);
> -             msg_set_destnode(hdr, dnode);
> -             msg_set_destport(hdr, dport);
>               if (unlikely(!dport && !dnode))
>                       return -EHOSTUNREACH;
>       } else if (dest->addrtype == TIPC_ADDR_ID) {
>               dnode = dest->addr.id.node;
> -             msg_set_type(hdr, TIPC_DIRECT_MSG);
> -             msg_set_lookup_scope(hdr, 0);
> -             msg_set_destnode(hdr, dnode);
> -             msg_set_destport(hdr, dest->addr.id.ref);
> -             msg_set_hdr_sz(hdr, BASIC_H_SIZE);
>       } else {
>               return -EINVAL;
>       }
> @@ -1442,6 +1430,22 @@ static int __tipc_sendmsg(struct socket *sock, struct 
> msghdr *m, size_t dlen)
>       if (unlikely(rc))
>               return rc;
> 
> +     if (dest->addrtype == TIPC_ADDR_NAME) {
> +             msg_set_type(hdr, TIPC_NAMED_MSG);
> +             msg_set_hdr_sz(hdr, NAMED_H_SIZE);
> +             msg_set_nametype(hdr, type);
> +             msg_set_nameinst(hdr, inst);
> +             msg_set_lookup_scope(hdr, tipc_node2scope(dnode));
> +             msg_set_destnode(hdr, dnode);
> +             msg_set_destport(hdr, dport);
> +     } else { /* TIPC_ADDR_ID */
> +             msg_set_type(hdr, TIPC_DIRECT_MSG);
> +             msg_set_lookup_scope(hdr, 0);
> +             msg_set_destnode(hdr, dnode);
> +             msg_set_destport(hdr, dest->addr.id.ref);
> +             msg_set_hdr_sz(hdr, BASIC_H_SIZE);
> +     }
> +
>       __skb_queue_head_init(&pkts);
>       mtu = tipc_node_get_mtu(net, dnode, tsk->portid, false);
>       rc = tipc_msg_build(hdr, m, 0, dlen, mtu, &pkts);
> --
> 2.13.7


_______________________________________________
tipc-discussion mailing list
tipc-discussion@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tipc-discussion

Reply via email to