diff options
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 62 |
1 files changed, 43 insertions, 19 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index a8c10764f2f6..ce7d9be8833c 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -44,8 +44,6 @@ | |||
44 | #include "bcast.h" | 44 | #include "bcast.h" |
45 | #include "netlink.h" | 45 | #include "netlink.h" |
46 | 46 | ||
47 | #define SS_LISTENING -1 /* socket is listening */ | ||
48 | |||
49 | #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ | 47 | #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ |
50 | #define CONN_PROBING_INTERVAL msecs_to_jiffies(3600000) /* [ms] => 1 h */ | 48 | #define CONN_PROBING_INTERVAL msecs_to_jiffies(3600000) /* [ms] => 1 h */ |
51 | #define TIPC_FWD_MSG 1 | 49 | #define TIPC_FWD_MSG 1 |
@@ -54,6 +52,10 @@ | |||
54 | #define TIPC_MAX_PORT 0xffffffff | 52 | #define TIPC_MAX_PORT 0xffffffff |
55 | #define TIPC_MIN_PORT 1 | 53 | #define TIPC_MIN_PORT 1 |
56 | 54 | ||
55 | enum { | ||
56 | TIPC_LISTEN = TCP_LISTEN, | ||
57 | }; | ||
58 | |||
57 | /** | 59 | /** |
58 | * struct tipc_sock - TIPC socket structure | 60 | * struct tipc_sock - TIPC socket structure |
59 | * @sk: socket - interacts with 'port' and with user via the socket API | 61 | * @sk: socket - interacts with 'port' and with user via the socket API |
@@ -337,6 +339,31 @@ static bool tsk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg) | |||
337 | return false; | 339 | return false; |
338 | } | 340 | } |
339 | 341 | ||
342 | /* tipc_set_sk_state - set the sk_state of the socket | ||
343 | * @sk: socket | ||
344 | * | ||
345 | * Caller must hold socket lock | ||
346 | * | ||
347 | * Returns 0 on success, errno otherwise | ||
348 | */ | ||
349 | static int tipc_set_sk_state(struct sock *sk, int state) | ||
350 | { | ||
351 | int oldstate = sk->sk_socket->state; | ||
352 | int res = -EINVAL; | ||
353 | |||
354 | switch (state) { | ||
355 | case TIPC_LISTEN: | ||
356 | if (oldstate == SS_UNCONNECTED) | ||
357 | res = 0; | ||
358 | break; | ||
359 | } | ||
360 | |||
361 | if (!res) | ||
362 | sk->sk_state = state; | ||
363 | |||
364 | return res; | ||
365 | } | ||
366 | |||
340 | /** | 367 | /** |
341 | * tipc_sk_create - create a TIPC socket | 368 | * tipc_sk_create - create a TIPC socket |
342 | * @net: network namespace (must be default network) | 369 | * @net: network namespace (must be default network) |
@@ -666,15 +693,22 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock, | |||
666 | 693 | ||
667 | switch ((int)sock->state) { | 694 | switch ((int)sock->state) { |
668 | case SS_UNCONNECTED: | 695 | case SS_UNCONNECTED: |
669 | if (!tsk->link_cong) | 696 | switch (sk->sk_state) { |
670 | mask |= POLLOUT; | 697 | case TIPC_LISTEN: |
698 | if (!skb_queue_empty(&sk->sk_receive_queue)) | ||
699 | mask |= (POLLIN | POLLRDNORM); | ||
700 | break; | ||
701 | default: | ||
702 | if (!tsk->link_cong) | ||
703 | mask |= POLLOUT; | ||
704 | break; | ||
705 | } | ||
671 | break; | 706 | break; |
672 | case SS_CONNECTED: | 707 | case SS_CONNECTED: |
673 | if (!tsk->link_cong && !tsk_conn_cong(tsk)) | 708 | if (!tsk->link_cong && !tsk_conn_cong(tsk)) |
674 | mask |= POLLOUT; | 709 | mask |= POLLOUT; |
675 | /* fall thru' */ | 710 | /* fall thru' */ |
676 | case SS_CONNECTING: | 711 | case SS_CONNECTING: |
677 | case SS_LISTENING: | ||
678 | if (!skb_queue_empty(&sk->sk_receive_queue)) | 712 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
679 | mask |= (POLLIN | POLLRDNORM); | 713 | mask |= (POLLIN | POLLRDNORM); |
680 | break; | 714 | break; |
@@ -925,7 +959,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz) | |||
925 | return -EINVAL; | 959 | return -EINVAL; |
926 | } | 960 | } |
927 | if (!is_connectionless) { | 961 | if (!is_connectionless) { |
928 | if (sock->state == SS_LISTENING) | 962 | if (sk->sk_state == TIPC_LISTEN) |
929 | return -EPIPE; | 963 | return -EPIPE; |
930 | if (sock->state != SS_UNCONNECTED) | 964 | if (sock->state != SS_UNCONNECTED) |
931 | return -EISCONN; | 965 | return -EISCONN; |
@@ -1651,7 +1685,6 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb) | |||
1651 | msg_set_dest_droppable(hdr, 1); | 1685 | msg_set_dest_droppable(hdr, 1); |
1652 | return false; | 1686 | return false; |
1653 | 1687 | ||
1654 | case SS_LISTENING: | ||
1655 | case SS_UNCONNECTED: | 1688 | case SS_UNCONNECTED: |
1656 | 1689 | ||
1657 | /* Accept only SYN message */ | 1690 | /* Accept only SYN message */ |
@@ -2026,15 +2059,9 @@ static int tipc_listen(struct socket *sock, int len) | |||
2026 | int res; | 2059 | int res; |
2027 | 2060 | ||
2028 | lock_sock(sk); | 2061 | lock_sock(sk); |
2029 | 2062 | res = tipc_set_sk_state(sk, TIPC_LISTEN); | |
2030 | if (sock->state != SS_UNCONNECTED) | ||
2031 | res = -EINVAL; | ||
2032 | else { | ||
2033 | sock->state = SS_LISTENING; | ||
2034 | res = 0; | ||
2035 | } | ||
2036 | |||
2037 | release_sock(sk); | 2063 | release_sock(sk); |
2064 | |||
2038 | return res; | 2065 | return res; |
2039 | } | 2066 | } |
2040 | 2067 | ||
@@ -2060,9 +2087,6 @@ static int tipc_wait_for_accept(struct socket *sock, long timeo) | |||
2060 | err = 0; | 2087 | err = 0; |
2061 | if (!skb_queue_empty(&sk->sk_receive_queue)) | 2088 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
2062 | break; | 2089 | break; |
2063 | err = -EINVAL; | ||
2064 | if (sock->state != SS_LISTENING) | ||
2065 | break; | ||
2066 | err = -EAGAIN; | 2090 | err = -EAGAIN; |
2067 | if (!timeo) | 2091 | if (!timeo) |
2068 | break; | 2092 | break; |
@@ -2093,7 +2117,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags) | |||
2093 | 2117 | ||
2094 | lock_sock(sk); | 2118 | lock_sock(sk); |
2095 | 2119 | ||
2096 | if (sock->state != SS_LISTENING) { | 2120 | if (sk->sk_state != TIPC_LISTEN) { |
2097 | res = -EINVAL; | 2121 | res = -EINVAL; |
2098 | goto exit; | 2122 | goto exit; |
2099 | } | 2123 | } |