|
@@ -1509,8 +1509,13 @@ static int listen(struct socket *sock, int len)
|
|
|
*/
|
|
|
static int accept(struct socket *sock, struct socket *new_sock, int flags)
|
|
|
{
|
|
|
- struct sock *sk = sock->sk;
|
|
|
+ struct sock *new_sk, *sk = sock->sk;
|
|
|
struct sk_buff *buf;
|
|
|
+ struct tipc_sock *new_tsock;
|
|
|
+ struct tipc_port *new_tport;
|
|
|
+ struct tipc_msg *msg;
|
|
|
+ u32 new_ref;
|
|
|
+
|
|
|
int res;
|
|
|
|
|
|
lock_sock(sk);
|
|
@@ -1536,49 +1541,51 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags)
|
|
|
buf = skb_peek(&sk->sk_receive_queue);
|
|
|
|
|
|
res = tipc_create(sock_net(sock->sk), new_sock, 0, 0);
|
|
|
- if (!res) {
|
|
|
- struct sock *new_sk = new_sock->sk;
|
|
|
- struct tipc_sock *new_tsock = tipc_sk(new_sk);
|
|
|
- struct tipc_port *new_tport = new_tsock->p;
|
|
|
- u32 new_ref = new_tport->ref;
|
|
|
- struct tipc_msg *msg = buf_msg(buf);
|
|
|
-
|
|
|
- /* we lock on new_sk; but lockdep sees the lock on sk */
|
|
|
- lock_sock_nested(new_sk, SINGLE_DEPTH_NESTING);
|
|
|
-
|
|
|
- /*
|
|
|
- * Reject any stray messages received by new socket
|
|
|
- * before the socket lock was taken (very, very unlikely)
|
|
|
- */
|
|
|
- reject_rx_queue(new_sk);
|
|
|
-
|
|
|
- /* Connect new socket to it's peer */
|
|
|
- new_tsock->peer_name.ref = msg_origport(msg);
|
|
|
- new_tsock->peer_name.node = msg_orignode(msg);
|
|
|
- tipc_connect(new_ref, &new_tsock->peer_name);
|
|
|
- new_sock->state = SS_CONNECTED;
|
|
|
-
|
|
|
- tipc_set_portimportance(new_ref, msg_importance(msg));
|
|
|
- if (msg_named(msg)) {
|
|
|
- new_tport->conn_type = msg_nametype(msg);
|
|
|
- new_tport->conn_instance = msg_nameinst(msg);
|
|
|
- }
|
|
|
+ if (res)
|
|
|
+ goto exit;
|
|
|
|
|
|
- /*
|
|
|
- * Respond to 'SYN-' by discarding it & returning 'ACK'-.
|
|
|
- * Respond to 'SYN+' by queuing it on new socket.
|
|
|
- */
|
|
|
- if (!msg_data_sz(msg)) {
|
|
|
- struct msghdr m = {NULL,};
|
|
|
+ new_sk = new_sock->sk;
|
|
|
+ new_tsock = tipc_sk(new_sk);
|
|
|
+ new_tport = new_tsock->p;
|
|
|
+ new_ref = new_tport->ref;
|
|
|
+ msg = buf_msg(buf);
|
|
|
|
|
|
- advance_rx_queue(sk);
|
|
|
- send_packet(NULL, new_sock, &m, 0);
|
|
|
- } else {
|
|
|
- __skb_dequeue(&sk->sk_receive_queue);
|
|
|
- __skb_queue_head(&new_sk->sk_receive_queue, buf);
|
|
|
- }
|
|
|
- release_sock(new_sk);
|
|
|
+ /* we lock on new_sk; but lockdep sees the lock on sk */
|
|
|
+ lock_sock_nested(new_sk, SINGLE_DEPTH_NESTING);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Reject any stray messages received by new socket
|
|
|
+ * before the socket lock was taken (very, very unlikely)
|
|
|
+ */
|
|
|
+ reject_rx_queue(new_sk);
|
|
|
+
|
|
|
+ /* Connect new socket to it's peer */
|
|
|
+ new_tsock->peer_name.ref = msg_origport(msg);
|
|
|
+ new_tsock->peer_name.node = msg_orignode(msg);
|
|
|
+ tipc_connect(new_ref, &new_tsock->peer_name);
|
|
|
+ new_sock->state = SS_CONNECTED;
|
|
|
+
|
|
|
+ tipc_set_portimportance(new_ref, msg_importance(msg));
|
|
|
+ if (msg_named(msg)) {
|
|
|
+ new_tport->conn_type = msg_nametype(msg);
|
|
|
+ new_tport->conn_instance = msg_nameinst(msg);
|
|
|
}
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Respond to 'SYN-' by discarding it & returning 'ACK'-.
|
|
|
+ * Respond to 'SYN+' by queuing it on new socket.
|
|
|
+ */
|
|
|
+ if (!msg_data_sz(msg)) {
|
|
|
+ struct msghdr m = {NULL,};
|
|
|
+
|
|
|
+ advance_rx_queue(sk);
|
|
|
+ send_packet(NULL, new_sock, &m, 0);
|
|
|
+ } else {
|
|
|
+ __skb_dequeue(&sk->sk_receive_queue);
|
|
|
+ __skb_queue_head(&new_sk->sk_receive_queue, buf);
|
|
|
+ }
|
|
|
+ release_sock(new_sk);
|
|
|
+
|
|
|
exit:
|
|
|
release_sock(sk);
|
|
|
return res;
|