@@ -866,6 +866,14 @@ static void tipc_sk_proto_rcv(struct tipc_sock *tsk, struct sk_buff *skb,
866
866
if (!tsk_peer_msg (tsk , hdr ))
867
867
goto exit ;
868
868
869
+ if (unlikely (msg_errcode (hdr ))) {
870
+ tipc_set_sk_state (sk , TIPC_DISCONNECTING );
871
+ tipc_node_remove_conn (sock_net (sk ), tsk_peer_node (tsk ),
872
+ tsk_peer_port (tsk ));
873
+ sk -> sk_state_change (sk );
874
+ goto exit ;
875
+ }
876
+
869
877
tsk -> probe_unacked = false;
870
878
871
879
if (mtyp == CONN_PROBE ) {
@@ -1259,7 +1267,10 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)
1259
1267
struct sock * sk = sock -> sk ;
1260
1268
DEFINE_WAIT (wait );
1261
1269
long timeo = * timeop ;
1262
- int err ;
1270
+ int err = sock_error (sk );
1271
+
1272
+ if (err )
1273
+ return err ;
1263
1274
1264
1275
for (;;) {
1265
1276
prepare_to_wait (sk_sleep (sk ), & wait , TASK_INTERRUPTIBLE );
@@ -1281,6 +1292,10 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)
1281
1292
err = sock_intr_errno (timeo );
1282
1293
if (signal_pending (current ))
1283
1294
break ;
1295
+
1296
+ err = sock_error (sk );
1297
+ if (err )
1298
+ break ;
1284
1299
}
1285
1300
finish_wait (sk_sleep (sk ), & wait );
1286
1301
* timeop = timeo ;
@@ -1551,25 +1566,37 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
1551
1566
struct sock * sk = & tsk -> sk ;
1552
1567
struct net * net = sock_net (sk );
1553
1568
struct tipc_msg * hdr = buf_msg (skb );
1569
+ u32 pport = msg_origport (hdr );
1570
+ u32 pnode = msg_orignode (hdr );
1554
1571
1555
1572
if (unlikely (msg_mcast (hdr )))
1556
1573
return false;
1557
1574
1558
1575
switch (sk -> sk_state ) {
1559
1576
case TIPC_CONNECTING :
1560
1577
/* Accept only ACK or NACK message */
1561
- if (unlikely (!msg_connected (hdr )))
1562
- return false;
1578
+ if (unlikely (!msg_connected (hdr ))) {
1579
+ if (pport != tsk_peer_port (tsk ) ||
1580
+ pnode != tsk_peer_node (tsk ))
1581
+ return false;
1582
+
1583
+ tipc_set_sk_state (sk , TIPC_DISCONNECTING );
1584
+ sk -> sk_err = ECONNREFUSED ;
1585
+ sk -> sk_state_change (sk );
1586
+ return true;
1587
+ }
1563
1588
1564
1589
if (unlikely (msg_errcode (hdr ))) {
1565
1590
tipc_set_sk_state (sk , TIPC_DISCONNECTING );
1566
1591
sk -> sk_err = ECONNREFUSED ;
1592
+ sk -> sk_state_change (sk );
1567
1593
return true;
1568
1594
}
1569
1595
1570
1596
if (unlikely (!msg_isdata (hdr ))) {
1571
1597
tipc_set_sk_state (sk , TIPC_DISCONNECTING );
1572
1598
sk -> sk_err = EINVAL ;
1599
+ sk -> sk_state_change (sk );
1573
1600
return true;
1574
1601
}
1575
1602
@@ -1581,8 +1608,7 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
1581
1608
return true;
1582
1609
1583
1610
/* If empty 'ACK-' message, wake up sleeping connect() */
1584
- if (waitqueue_active (sk_sleep (sk )))
1585
- wake_up_interruptible (sk_sleep (sk ));
1611
+ sk -> sk_data_ready (sk );
1586
1612
1587
1613
/* 'ACK-' message is neither accepted nor rejected: */
1588
1614
msg_set_dest_droppable (hdr , 1 );
0 commit comments