54
54
TIPC_LISTEN = TCP_LISTEN ,
55
55
TIPC_ESTABLISHED = TCP_ESTABLISHED ,
56
56
TIPC_OPEN = TCP_CLOSE ,
57
+ TIPC_DISCONNECTING = TCP_CLOSE_WAIT ,
57
58
};
58
59
59
60
/**
@@ -362,10 +363,14 @@ static int tipc_set_sk_state(struct sock *sk, int state)
362
363
break ;
363
364
case TIPC_ESTABLISHED :
364
365
if (oldstate == SS_CONNECTING ||
365
- oldstate == SS_UNCONNECTED ||
366
366
oldsk_state == TIPC_OPEN )
367
367
res = 0 ;
368
368
break ;
369
+ case TIPC_DISCONNECTING :
370
+ if (oldstate == SS_CONNECTING ||
371
+ oldsk_state == TIPC_ESTABLISHED )
372
+ res = 0 ;
373
+ break ;
369
374
}
370
375
371
376
if (!res )
@@ -621,13 +626,14 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr,
621
626
int * uaddr_len , int peer )
622
627
{
623
628
struct sockaddr_tipc * addr = (struct sockaddr_tipc * )uaddr ;
624
- struct tipc_sock * tsk = tipc_sk (sock -> sk );
629
+ struct sock * sk = sock -> sk ;
630
+ struct tipc_sock * tsk = tipc_sk (sk );
625
631
struct tipc_net * tn = net_generic (sock_net (sock -> sk ), tipc_net_id );
626
632
627
633
memset (addr , 0 , sizeof (* addr ));
628
634
if (peer ) {
629
635
if ((sock -> state != SS_CONNECTED ) &&
630
- ((peer != 2 ) || (sock -> state != SS_DISCONNECTING )))
636
+ ((peer != 2 ) || (sk -> sk_state != TIPC_DISCONNECTING )))
631
637
return - ENOTCONN ;
632
638
addr -> addr .id .ref = tsk_peer_port (tsk );
633
639
addr -> addr .id .node = tsk_peer_node (tsk );
@@ -693,6 +699,9 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
693
699
(!skb_queue_empty (& sk -> sk_receive_queue )))
694
700
mask |= (POLLIN | POLLRDNORM );
695
701
break ;
702
+ case TIPC_DISCONNECTING :
703
+ mask = (POLLIN | POLLRDNORM | POLLHUP );
704
+ break ;
696
705
case TIPC_LISTEN :
697
706
if (!skb_queue_empty (& sk -> sk_receive_queue ))
698
707
mask |= (POLLIN | POLLRDNORM );
@@ -1028,7 +1037,7 @@ static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p)
1028
1037
int err = sock_error (sk );
1029
1038
if (err )
1030
1039
return err ;
1031
- if (sock -> state == SS_DISCONNECTING )
1040
+ if (sk -> sk_state == TIPC_DISCONNECTING )
1032
1041
return - EPIPE ;
1033
1042
else if (sock -> state != SS_CONNECTED )
1034
1043
return - ENOTCONN ;
@@ -1098,7 +1107,7 @@ static int __tipc_send_stream(struct socket *sock, struct msghdr *m, size_t dsz)
1098
1107
return - EMSGSIZE ;
1099
1108
1100
1109
if (unlikely (sock -> state != SS_CONNECTED )) {
1101
- if (sock -> state == SS_DISCONNECTING )
1110
+ if (sk -> sk_state == TIPC_DISCONNECTING )
1102
1111
return - EPIPE ;
1103
1112
else
1104
1113
return - ENOTCONN ;
@@ -1626,7 +1635,7 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
1626
1635
return false;
1627
1636
1628
1637
if (unlikely (msg_errcode (hdr ))) {
1629
- sock -> state = SS_DISCONNECTING ;
1638
+ tipc_set_sk_state ( sk , TIPC_DISCONNECTING ) ;
1630
1639
/* Let timer expire on it's own */
1631
1640
tipc_node_remove_conn (net , tsk_peer_node (tsk ),
1632
1641
tsk -> portid );
@@ -1641,13 +1650,13 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
1641
1650
return false;
1642
1651
1643
1652
if (unlikely (msg_errcode (hdr ))) {
1644
- sock -> state = SS_DISCONNECTING ;
1653
+ tipc_set_sk_state ( sk , TIPC_DISCONNECTING ) ;
1645
1654
sk -> sk_err = ECONNREFUSED ;
1646
1655
return true;
1647
1656
}
1648
1657
1649
1658
if (unlikely (!msg_isdata (hdr ))) {
1650
- sock -> state = SS_DISCONNECTING ;
1659
+ tipc_set_sk_state ( sk , TIPC_DISCONNECTING ) ;
1651
1660
sk -> sk_err = EINVAL ;
1652
1661
return true;
1653
1662
}
@@ -1674,6 +1683,7 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
1674
1683
1675
1684
switch (sk -> sk_state ) {
1676
1685
case TIPC_OPEN :
1686
+ case TIPC_DISCONNECTING :
1677
1687
break ;
1678
1688
case TIPC_LISTEN :
1679
1689
/* Accept only SYN message */
@@ -2195,9 +2205,7 @@ static int tipc_shutdown(struct socket *sock, int how)
2195
2205
2196
2206
lock_sock (sk );
2197
2207
2198
- switch (sock -> state ) {
2199
- case SS_CONNECTING :
2200
- case SS_CONNECTED :
2208
+ if (sock -> state == SS_CONNECTING || sock -> state == SS_CONNECTED ) {
2201
2209
2202
2210
restart :
2203
2211
dnode = tsk_peer_node (tsk );
@@ -2218,11 +2226,12 @@ static int tipc_shutdown(struct socket *sock, int how)
2218
2226
if (skb )
2219
2227
tipc_node_xmit_skb (net , skb , dnode , tsk -> portid );
2220
2228
}
2221
- sock -> state = SS_DISCONNECTING ;
2229
+ tipc_set_sk_state ( sk , TIPC_DISCONNECTING ) ;
2222
2230
tipc_node_remove_conn (net , dnode , tsk -> portid );
2223
- /* fall through */
2231
+ }
2224
2232
2225
- case SS_DISCONNECTING :
2233
+ switch (sk -> sk_state ) {
2234
+ case TIPC_DISCONNECTING :
2226
2235
2227
2236
/* Discard any unreceived messages */
2228
2237
__skb_queue_purge (& sk -> sk_receive_queue );
@@ -2258,7 +2267,7 @@ static void tipc_sk_timeout(unsigned long data)
2258
2267
2259
2268
if (tsk -> probe_unacked ) {
2260
2269
if (!sock_owned_by_user (sk )) {
2261
- sk -> sk_socket -> state = SS_DISCONNECTING ;
2270
+ tipc_set_sk_state ( sk , TIPC_DISCONNECTING ) ;
2262
2271
tipc_node_remove_conn (sock_net (sk ), tsk_peer_node (tsk ),
2263
2272
tsk_peer_port (tsk ));
2264
2273
sk -> sk_state_change (sk );
0 commit comments