diff options
Diffstat (limited to 'net/tipc/socket.c')
| -rw-r--r-- | net/tipc/socket.c | 75 | 
1 files changed, 37 insertions, 38 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index f202d4790ce3..a65105818fe5 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -45,6 +45,7 @@  #define SS_READY	-2	/* socket is connectionless */  #define CONN_TIMEOUT_DEFAULT	8000	/* default connect timeout = 8s */ +#define CONN_PROBING_INTERVAL 3600000	/* [ms] => 1 h */  #define TIPC_FWD_MSG	        1  static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb); @@ -339,7 +340,9 @@ static int tipc_release(struct socket *sock)  			if ((sock->state == SS_CONNECTING) ||  			    (sock->state == SS_CONNECTED)) {  				sock->state = SS_DISCONNECTING; -				tipc_port_disconnect(port->ref); +				port->connected = 0; +				tipc_node_remove_conn(tipc_port_peernode(port), +						      port->ref);  			}  			if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT))  				tipc_link_xmit(buf, dnode, 0); @@ -988,29 +991,25 @@ static int tipc_send_packet(struct kiocb *iocb, struct socket *sock,  	return tipc_send_stream(iocb, sock, m, dsz);  } -/** - * auto_connect - complete connection setup to a remote port - * @tsk: tipc socket structure - * @msg: peer's response message - * - * Returns 0 on success, errno otherwise +/* tipc_sk_finish_conn - complete the setup of a connection   */ -static int auto_connect(struct tipc_sock *tsk, struct tipc_msg *msg) +static void tipc_sk_finish_conn(struct tipc_port *port, u32 peer_port, +				u32 peer_node)  { -	struct tipc_port *port = &tsk->port; -	struct socket *sock = tsk->sk.sk_socket; -	struct tipc_portid peer; - -	peer.ref = msg_origport(msg); -	peer.node = msg_orignode(msg); +	struct tipc_msg *msg = &port->phdr; -	__tipc_port_connect(port->ref, port, &peer); +	msg_set_destnode(msg, peer_node); +	msg_set_destport(msg, peer_port); +	msg_set_type(msg, TIPC_CONN_MSG); +	msg_set_lookup_scope(msg, 0); +	msg_set_hdr_sz(msg, SHORT_H_SIZE); -	if (msg_importance(msg) > TIPC_CRITICAL_IMPORTANCE) -		return -EINVAL; -	msg_set_importance(&port->phdr, (u32)msg_importance(msg)); -	sock->state = SS_CONNECTED; -	return 0; +	port->probing_interval = CONN_PROBING_INTERVAL; +	port->probing_state = TIPC_CONN_OK; +	port->connected = 1; +	k_start_timer(&port->timer, port->probing_interval); +	tipc_node_add_conn(peer_node, port->ref, peer_port); +	port->max_pkt = tipc_node_get_mtu(peer_node, port->ref);  }  /** @@ -1405,7 +1404,6 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)  	struct tipc_msg *msg = buf_msg(*buf);  	int retval = -TIPC_ERR_NO_PORT; -	int res;  	if (msg_mcast(msg))  		return retval; @@ -1416,13 +1414,20 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)  		if (msg_connected(msg) && tipc_port_peer_msg(port, msg)) {  			if (unlikely(msg_errcode(msg))) {  				sock->state = SS_DISCONNECTING; -				__tipc_port_disconnect(port); +				port->connected = 0; +				/* let timer expire on it's own */ +				tipc_node_remove_conn(tipc_port_peernode(port), +						      port->ref);  			}  			retval = TIPC_OK;  		}  		break;  	case SS_CONNECTING:  		/* Accept only ACK or NACK message */ + +		if (unlikely(!msg_connected(msg))) +			break; +  		if (unlikely(msg_errcode(msg))) {  			sock->state = SS_DISCONNECTING;  			sk->sk_err = ECONNREFUSED; @@ -1430,17 +1435,17 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)  			break;  		} -		if (unlikely(!msg_connected(msg))) -			break; - -		res = auto_connect(tsk, msg); -		if (res) { +		if (unlikely(msg_importance(msg) > TIPC_CRITICAL_IMPORTANCE)) {  			sock->state = SS_DISCONNECTING; -			sk->sk_err = -res; +			sk->sk_err = EINVAL;  			retval = TIPC_OK;  			break;  		} +		tipc_sk_finish_conn(port, msg_origport(msg), msg_orignode(msg)); +		msg_set_importance(&port->phdr, msg_importance(msg)); +		sock->state = SS_CONNECTED; +  		/* If an incoming message is an 'ACK-', it should be  		 * discarded here because it doesn't contain useful  		 * data. In addition, we should try to wake up @@ -1816,8 +1821,6 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)  	struct sk_buff *buf;  	struct tipc_port *new_port;  	struct tipc_msg *msg; -	struct tipc_portid peer; -	u32 new_ref;  	long timeo;  	int res; @@ -1840,7 +1843,6 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)  	new_sk = new_sock->sk;  	new_port = &tipc_sk(new_sk)->port; -	new_ref = new_port->ref;  	msg = buf_msg(buf);  	/* we lock on new_sk; but lockdep sees the lock on sk */ @@ -1853,9 +1855,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)  	reject_rx_queue(new_sk);  	/* Connect new socket to it's peer */ -	peer.ref = msg_origport(msg); -	peer.node = msg_orignode(msg); -	tipc_port_connect(new_ref, &peer); +	tipc_sk_finish_conn(new_port, msg_origport(msg), msg_orignode(msg));  	new_sock->state = SS_CONNECTED;  	tipc_port_set_importance(new_port, msg_importance(msg)); @@ -1919,9 +1919,9 @@ restart:  				kfree_skb(buf);  				goto restart;  			} -			tipc_port_disconnect(port->ref);  			if (tipc_msg_reverse(buf, &dnode, TIPC_CONN_SHUTDOWN))  				tipc_link_xmit(buf, dnode, port->ref); +			tipc_node_remove_conn(dnode, port->ref);  		} else {  			dnode = tipc_port_peernode(port);  			buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, @@ -1930,11 +1930,10 @@ restart:  					      tipc_port_peerport(port),  					      port->ref, TIPC_CONN_SHUTDOWN);  			tipc_link_xmit(buf, dnode, port->ref); -			__tipc_port_disconnect(port);  		} - +		port->connected = 0;  		sock->state = SS_DISCONNECTING; - +		tipc_node_remove_conn(dnode, port->ref);  		/* fall through */  	case SS_DISCONNECTING:  | 
