diff options
Diffstat (limited to 'net/tipc')
| -rw-r--r-- | net/tipc/Makefile | 4 | ||||
| -rw-r--r-- | net/tipc/netlink_compat.c | 4 | ||||
| -rw-r--r-- | net/tipc/socket.c | 57 | 
3 files changed, 37 insertions, 28 deletions
diff --git a/net/tipc/Makefile b/net/tipc/Makefile index 11255e970dd4..ee49a9f1dd4f 100644 --- a/net/tipc/Makefile +++ b/net/tipc/Makefile @@ -9,7 +9,7 @@ tipc-y	+= addr.o bcast.o bearer.o \  	   core.o link.o discover.o msg.o  \  	   name_distr.o  subscr.o monitor.o name_table.o net.o  \  	   netlink.o netlink_compat.o node.o socket.o eth_media.o \ -	   topsrv.o socket.o group.o trace.o +	   topsrv.o group.o trace.o  CFLAGS_trace.o += -I$(src) @@ -20,5 +20,3 @@ tipc-$(CONFIG_TIPC_CRYPTO)	+= crypto.o  obj-$(CONFIG_TIPC_DIAG)	+= diag.o - -tipc_diag-y	:= diag.o diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 0254bb7e418b..217516357ef2 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -204,8 +204,8 @@ static int __tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd,  		return -ENOMEM;  	} -	attrbuf = kmalloc_array(tipc_genl_family.maxattr + 1, -				sizeof(struct nlattr *), GFP_KERNEL); +	attrbuf = kcalloc(tipc_genl_family.maxattr + 1, +			  sizeof(struct nlattr *), GFP_KERNEL);  	if (!attrbuf) {  		err = -ENOMEM;  		goto err_out; diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 6552f986774c..f9b4fb92c0b1 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -287,12 +287,12 @@ static void tipc_sk_respond(struct sock *sk, struct sk_buff *skb, int err)   *   * Caller must hold socket lock   */ -static void tsk_rej_rx_queue(struct sock *sk) +static void tsk_rej_rx_queue(struct sock *sk, int error)  {  	struct sk_buff *skb;  	while ((skb = __skb_dequeue(&sk->sk_receive_queue))) -		tipc_sk_respond(sk, skb, TIPC_ERR_NO_PORT); +		tipc_sk_respond(sk, skb, error);  }  static bool tipc_sk_connected(struct sock *sk) @@ -545,34 +545,45 @@ static void __tipc_shutdown(struct socket *sock, int error)  	/* Remove pending SYN */  	__skb_queue_purge(&sk->sk_write_queue); -	/* Reject all unreceived messages, except on an active connection -	 * (which disconnects locally & sends a 'FIN+' to peer). -	 */ -	while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) { -		if (TIPC_SKB_CB(skb)->bytes_read) { -			kfree_skb(skb); -			continue; -		} -		if (!tipc_sk_type_connectionless(sk) && -		    sk->sk_state != TIPC_DISCONNECTING) { -			tipc_set_sk_state(sk, TIPC_DISCONNECTING); -			tipc_node_remove_conn(net, dnode, tsk->portid); -		} -		tipc_sk_respond(sk, skb, error); +	/* Remove partially received buffer if any */ +	skb = skb_peek(&sk->sk_receive_queue); +	if (skb && TIPC_SKB_CB(skb)->bytes_read) { +		__skb_unlink(skb, &sk->sk_receive_queue); +		kfree_skb(skb);  	} -	if (tipc_sk_type_connectionless(sk)) +	/* Reject all unreceived messages if connectionless */ +	if (tipc_sk_type_connectionless(sk)) { +		tsk_rej_rx_queue(sk, error);  		return; +	} -	if (sk->sk_state != TIPC_DISCONNECTING) { +	switch (sk->sk_state) { +	case TIPC_CONNECTING: +	case TIPC_ESTABLISHED: +		tipc_set_sk_state(sk, TIPC_DISCONNECTING); +		tipc_node_remove_conn(net, dnode, tsk->portid); +		/* Send a FIN+/- to its peer */ +		skb = __skb_dequeue(&sk->sk_receive_queue); +		if (skb) { +			__skb_queue_purge(&sk->sk_receive_queue); +			tipc_sk_respond(sk, skb, error); +			break; +		}  		skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,  				      TIPC_CONN_MSG, SHORT_H_SIZE, 0, dnode,  				      tsk_own_node(tsk), tsk_peer_port(tsk),  				      tsk->portid, error);  		if (skb)  			tipc_node_xmit_skb(net, skb, dnode, tsk->portid); -		tipc_node_remove_conn(net, dnode, tsk->portid); -		tipc_set_sk_state(sk, TIPC_DISCONNECTING); +		break; +	case TIPC_LISTEN: +		/* Reject all SYN messages */ +		tsk_rej_rx_queue(sk, error); +		break; +	default: +		__skb_queue_purge(&sk->sk_receive_queue); +		break;  	}  } @@ -2432,8 +2443,8 @@ static int tipc_wait_for_connect(struct socket *sock, long *timeo_p)  			return sock_intr_errno(*timeo_p);  		add_wait_queue(sk_sleep(sk), &wait); -		done = sk_wait_event(sk, timeo_p, -				     sk->sk_state != TIPC_CONNECTING, &wait); +		done = sk_wait_event(sk, timeo_p, tipc_sk_connected(sk), +				     &wait);  		remove_wait_queue(sk_sleep(sk), &wait);  	} while (!done);  	return 0; @@ -2643,7 +2654,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags,  	 * Reject any stray messages received by new socket  	 * before the socket lock was taken (very, very unlikely)  	 */ -	tsk_rej_rx_queue(new_sk); +	tsk_rej_rx_queue(new_sk, TIPC_ERR_NO_PORT);  	/* Connect new socket to it's peer */  	tipc_sk_finish_conn(new_tsock, msg_origport(msg), msg_orignode(msg));  | 
