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: |