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