diff options
author | Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com> | 2016-11-01 09:02:46 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-11-01 11:53:25 -0400 |
commit | 9fd4b070f6311faa7ba1ae746e955fedfbe3e045 (patch) | |
tree | 449485ad52aa9d446575e7031059d20e84051bdc /net/tipc/socket.c | |
parent | 438adcaf0df181fb6bf2afa917c741cc8c9241c3 (diff) |
tipc: create TIPC_DISCONNECTING as a new sk_state
In this commit, we create a new tipc socket state TIPC_DISCONNECTING in
sk_state. TIPC_DISCONNECTING is replacing the socket connection status
update using SS_DISCONNECTING.
TIPC_DISCONNECTING is set for connection oriented sockets at:
- tipc_shutdown()
- connection probe timeout
- when we receive an error message on the connection.
There is no functional change in this commit.
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index b14dd2549980..a48c0c0676cf 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -54,6 +54,7 @@ enum { | |||
54 | TIPC_LISTEN = TCP_LISTEN, | 54 | TIPC_LISTEN = TCP_LISTEN, |
55 | TIPC_ESTABLISHED = TCP_ESTABLISHED, | 55 | TIPC_ESTABLISHED = TCP_ESTABLISHED, |
56 | TIPC_OPEN = TCP_CLOSE, | 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 | break; | 363 | break; |
363 | case TIPC_ESTABLISHED: | 364 | case TIPC_ESTABLISHED: |
364 | if (oldstate == SS_CONNECTING || | 365 | if (oldstate == SS_CONNECTING || |
365 | oldstate == SS_UNCONNECTED || | ||
366 | oldsk_state == TIPC_OPEN) | 366 | oldsk_state == TIPC_OPEN) |
367 | res = 0; | 367 | res = 0; |
368 | break; | 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 | if (!res) | 376 | if (!res) |
@@ -621,13 +626,14 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr, | |||
621 | int *uaddr_len, int peer) | 626 | int *uaddr_len, int peer) |
622 | { | 627 | { |
623 | struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; | 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 | struct tipc_net *tn = net_generic(sock_net(sock->sk), tipc_net_id); | 631 | struct tipc_net *tn = net_generic(sock_net(sock->sk), tipc_net_id); |
626 | 632 | ||
627 | memset(addr, 0, sizeof(*addr)); | 633 | memset(addr, 0, sizeof(*addr)); |
628 | if (peer) { | 634 | if (peer) { |
629 | if ((sock->state != SS_CONNECTED) && | 635 | if ((sock->state != SS_CONNECTED) && |
630 | ((peer != 2) || (sock->state != SS_DISCONNECTING))) | 636 | ((peer != 2) || (sk->sk_state != TIPC_DISCONNECTING))) |
631 | return -ENOTCONN; | 637 | return -ENOTCONN; |
632 | addr->addr.id.ref = tsk_peer_port(tsk); | 638 | addr->addr.id.ref = tsk_peer_port(tsk); |
633 | addr->addr.id.node = tsk_peer_node(tsk); | 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 | (!skb_queue_empty(&sk->sk_receive_queue))) | 699 | (!skb_queue_empty(&sk->sk_receive_queue))) |
694 | mask |= (POLLIN | POLLRDNORM); | 700 | mask |= (POLLIN | POLLRDNORM); |
695 | break; | 701 | break; |
702 | case TIPC_DISCONNECTING: | ||
703 | mask = (POLLIN | POLLRDNORM | POLLHUP); | ||
704 | break; | ||
696 | case TIPC_LISTEN: | 705 | case TIPC_LISTEN: |
697 | if (!skb_queue_empty(&sk->sk_receive_queue)) | 706 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
698 | mask |= (POLLIN | POLLRDNORM); | 707 | mask |= (POLLIN | POLLRDNORM); |
@@ -1028,7 +1037,7 @@ static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p) | |||
1028 | int err = sock_error(sk); | 1037 | int err = sock_error(sk); |
1029 | if (err) | 1038 | if (err) |
1030 | return err; | 1039 | return err; |
1031 | if (sock->state == SS_DISCONNECTING) | 1040 | if (sk->sk_state == TIPC_DISCONNECTING) |
1032 | return -EPIPE; | 1041 | return -EPIPE; |
1033 | else if (sock->state != SS_CONNECTED) | 1042 | else if (sock->state != SS_CONNECTED) |
1034 | return -ENOTCONN; | 1043 | return -ENOTCONN; |
@@ -1098,7 +1107,7 @@ static int __tipc_send_stream(struct socket *sock, struct msghdr *m, size_t dsz) | |||
1098 | return -EMSGSIZE; | 1107 | return -EMSGSIZE; |
1099 | 1108 | ||
1100 | if (unlikely(sock->state != SS_CONNECTED)) { | 1109 | if (unlikely(sock->state != SS_CONNECTED)) { |
1101 | if (sock->state == SS_DISCONNECTING) | 1110 | if (sk->sk_state == TIPC_DISCONNECTING) |
1102 | return -EPIPE; | 1111 | return -EPIPE; |
1103 | else | 1112 | else |
1104 | return -ENOTCONN; | 1113 | return -ENOTCONN; |
@@ -1626,7 +1635,7 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb) | |||
1626 | return false; | 1635 | return false; |
1627 | 1636 | ||
1628 | if (unlikely(msg_errcode(hdr))) { | 1637 | if (unlikely(msg_errcode(hdr))) { |
1629 | sock->state = SS_DISCONNECTING; | 1638 | tipc_set_sk_state(sk, TIPC_DISCONNECTING); |
1630 | /* Let timer expire on it's own */ | 1639 | /* Let timer expire on it's own */ |
1631 | tipc_node_remove_conn(net, tsk_peer_node(tsk), | 1640 | tipc_node_remove_conn(net, tsk_peer_node(tsk), |
1632 | tsk->portid); | 1641 | tsk->portid); |
@@ -1641,13 +1650,13 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb) | |||
1641 | return false; | 1650 | return false; |
1642 | 1651 | ||
1643 | if (unlikely(msg_errcode(hdr))) { | 1652 | if (unlikely(msg_errcode(hdr))) { |
1644 | sock->state = SS_DISCONNECTING; | 1653 | tipc_set_sk_state(sk, TIPC_DISCONNECTING); |
1645 | sk->sk_err = ECONNREFUSED; | 1654 | sk->sk_err = ECONNREFUSED; |
1646 | return true; | 1655 | return true; |
1647 | } | 1656 | } |
1648 | 1657 | ||
1649 | if (unlikely(!msg_isdata(hdr))) { | 1658 | if (unlikely(!msg_isdata(hdr))) { |
1650 | sock->state = SS_DISCONNECTING; | 1659 | tipc_set_sk_state(sk, TIPC_DISCONNECTING); |
1651 | sk->sk_err = EINVAL; | 1660 | sk->sk_err = EINVAL; |
1652 | return true; | 1661 | return true; |
1653 | } | 1662 | } |
@@ -1674,6 +1683,7 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb) | |||
1674 | 1683 | ||
1675 | switch (sk->sk_state) { | 1684 | switch (sk->sk_state) { |
1676 | case TIPC_OPEN: | 1685 | case TIPC_OPEN: |
1686 | case TIPC_DISCONNECTING: | ||
1677 | break; | 1687 | break; |
1678 | case TIPC_LISTEN: | 1688 | case TIPC_LISTEN: |
1679 | /* Accept only SYN message */ | 1689 | /* Accept only SYN message */ |
@@ -2195,9 +2205,7 @@ static int tipc_shutdown(struct socket *sock, int how) | |||
2195 | 2205 | ||
2196 | lock_sock(sk); | 2206 | lock_sock(sk); |
2197 | 2207 | ||
2198 | switch (sock->state) { | 2208 | if (sock->state == SS_CONNECTING || sock->state == SS_CONNECTED) { |
2199 | case SS_CONNECTING: | ||
2200 | case SS_CONNECTED: | ||
2201 | 2209 | ||
2202 | restart: | 2210 | restart: |
2203 | dnode = tsk_peer_node(tsk); | 2211 | dnode = tsk_peer_node(tsk); |
@@ -2218,11 +2226,12 @@ restart: | |||
2218 | if (skb) | 2226 | if (skb) |
2219 | tipc_node_xmit_skb(net, skb, dnode, tsk->portid); | 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 | tipc_node_remove_conn(net, dnode, tsk->portid); | 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 | /* Discard any unreceived messages */ | 2236 | /* Discard any unreceived messages */ |
2228 | __skb_queue_purge(&sk->sk_receive_queue); | 2237 | __skb_queue_purge(&sk->sk_receive_queue); |
@@ -2258,7 +2267,7 @@ static void tipc_sk_timeout(unsigned long data) | |||
2258 | 2267 | ||
2259 | if (tsk->probe_unacked) { | 2268 | if (tsk->probe_unacked) { |
2260 | if (!sock_owned_by_user(sk)) { | 2269 | if (!sock_owned_by_user(sk)) { |
2261 | sk->sk_socket->state = SS_DISCONNECTING; | 2270 | tipc_set_sk_state(sk, TIPC_DISCONNECTING); |
2262 | tipc_node_remove_conn(sock_net(sk), tsk_peer_node(tsk), | 2271 | tipc_node_remove_conn(sock_net(sk), tsk_peer_node(tsk), |
2263 | tsk_peer_port(tsk)); | 2272 | tsk_peer_port(tsk)); |
2264 | sk->sk_state_change(sk); | 2273 | sk->sk_state_change(sk); |