aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2016-12-22 07:22:29 -0500
committerDavid S. Miller <davem@davemloft.net>2016-12-23 17:53:47 -0500
commit693c56491fb720087437a635e6eaf440659b922f (patch)
tree2889cdc6f954142ec0f054d435cf2dd5c2250b3d /net/tipc
parente252536068efd1578c6e23e7323527c5e6e980bd (diff)
tipc: don't send FIN message from connectionless socket
In commit 6f00089c7372 ("tipc: remove SS_DISCONNECTING state") the check for socket type is in the wrong place, causing a closing socket to always send out a FIN message even when the socket was never connected. This is normally harmless, since the destination node for such messages most often is zero, and the message will be dropped, but it is still a wrong and confusing behavior. We fix this in this commit. Reviewed-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/socket.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 333c5dae0072..800caaa699a1 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -441,15 +441,19 @@ static void __tipc_shutdown(struct socket *sock, int error)
441 while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) { 441 while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) {
442 if (TIPC_SKB_CB(skb)->bytes_read) { 442 if (TIPC_SKB_CB(skb)->bytes_read) {
443 kfree_skb(skb); 443 kfree_skb(skb);
444 } else { 444 continue;
445 if (!tipc_sk_type_connectionless(sk) && 445 }
446 sk->sk_state != TIPC_DISCONNECTING) { 446 if (!tipc_sk_type_connectionless(sk) &&
447 tipc_set_sk_state(sk, TIPC_DISCONNECTING); 447 sk->sk_state != TIPC_DISCONNECTING) {
448 tipc_node_remove_conn(net, dnode, tsk->portid); 448 tipc_set_sk_state(sk, TIPC_DISCONNECTING);
449 } 449 tipc_node_remove_conn(net, dnode, tsk->portid);
450 tipc_sk_respond(sk, skb, error);
451 } 450 }
451 tipc_sk_respond(sk, skb, error);
452 } 452 }
453
454 if (tipc_sk_type_connectionless(sk))
455 return;
456
453 if (sk->sk_state != TIPC_DISCONNECTING) { 457 if (sk->sk_state != TIPC_DISCONNECTING) {
454 skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, 458 skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
455 TIPC_CONN_MSG, SHORT_H_SIZE, 0, dnode, 459 TIPC_CONN_MSG, SHORT_H_SIZE, 0, dnode,
@@ -457,10 +461,8 @@ static void __tipc_shutdown(struct socket *sock, int error)
457 tsk->portid, error); 461 tsk->portid, error);
458 if (skb) 462 if (skb)
459 tipc_node_xmit_skb(net, skb, dnode, tsk->portid); 463 tipc_node_xmit_skb(net, skb, dnode, tsk->portid);
460 if (!tipc_sk_type_connectionless(sk)) { 464 tipc_node_remove_conn(net, dnode, tsk->portid);
461 tipc_node_remove_conn(net, dnode, tsk->portid); 465 tipc_set_sk_state(sk, TIPC_DISCONNECTING);
462 tipc_set_sk_state(sk, TIPC_DISCONNECTING);
463 }
464 } 466 }
465} 467}
466 468