diff options
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 5bceebd81f64..c03a3d33806f 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -74,6 +74,7 @@ | |||
74 | * @link_cong: non-zero if owner must sleep because of link congestion | 74 | * @link_cong: non-zero if owner must sleep because of link congestion |
75 | * @sent_unacked: # messages sent by socket, and not yet acked by peer | 75 | * @sent_unacked: # messages sent by socket, and not yet acked by peer |
76 | * @rcv_unacked: # messages read by user, but not yet acked back to peer | 76 | * @rcv_unacked: # messages read by user, but not yet acked back to peer |
77 | * @remote: 'connected' peer for dgram/rdm | ||
77 | * @node: hash table node | 78 | * @node: hash table node |
78 | * @rcu: rcu struct for tipc_sock | 79 | * @rcu: rcu struct for tipc_sock |
79 | */ | 80 | */ |
@@ -96,6 +97,7 @@ struct tipc_sock { | |||
96 | bool link_cong; | 97 | bool link_cong; |
97 | uint sent_unacked; | 98 | uint sent_unacked; |
98 | uint rcv_unacked; | 99 | uint rcv_unacked; |
100 | struct sockaddr_tipc remote; | ||
99 | struct rhash_head node; | 101 | struct rhash_head node; |
100 | struct rcu_head rcu; | 102 | struct rcu_head rcu; |
101 | }; | 103 | }; |
@@ -854,22 +856,23 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz) | |||
854 | u32 dnode, dport; | 856 | u32 dnode, dport; |
855 | struct sk_buff_head *pktchain = &sk->sk_write_queue; | 857 | struct sk_buff_head *pktchain = &sk->sk_write_queue; |
856 | struct sk_buff *skb; | 858 | struct sk_buff *skb; |
857 | struct tipc_name_seq *seq = &dest->addr.nameseq; | 859 | struct tipc_name_seq *seq; |
858 | struct iov_iter save; | 860 | struct iov_iter save; |
859 | u32 mtu; | 861 | u32 mtu; |
860 | long timeo; | 862 | long timeo; |
861 | int rc; | 863 | int rc; |
862 | 864 | ||
863 | if (unlikely(!dest)) | ||
864 | return -EDESTADDRREQ; | ||
865 | |||
866 | if (unlikely((m->msg_namelen < sizeof(*dest)) || | ||
867 | (dest->family != AF_TIPC))) | ||
868 | return -EINVAL; | ||
869 | |||
870 | if (dsz > TIPC_MAX_USER_MSG_SIZE) | 865 | if (dsz > TIPC_MAX_USER_MSG_SIZE) |
871 | return -EMSGSIZE; | 866 | return -EMSGSIZE; |
872 | 867 | if (unlikely(!dest)) { | |
868 | if (tsk->connected && sock->state == SS_READY) | ||
869 | dest = &tsk->remote; | ||
870 | else | ||
871 | return -EDESTADDRREQ; | ||
872 | } else if (unlikely(m->msg_namelen < sizeof(*dest)) || | ||
873 | dest->family != AF_TIPC) { | ||
874 | return -EINVAL; | ||
875 | } | ||
873 | if (unlikely(sock->state != SS_READY)) { | 876 | if (unlikely(sock->state != SS_READY)) { |
874 | if (sock->state == SS_LISTENING) | 877 | if (sock->state == SS_LISTENING) |
875 | return -EPIPE; | 878 | return -EPIPE; |
@@ -882,7 +885,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz) | |||
882 | tsk->conn_instance = dest->addr.name.name.instance; | 885 | tsk->conn_instance = dest->addr.name.name.instance; |
883 | } | 886 | } |
884 | } | 887 | } |
885 | 888 | seq = &dest->addr.nameseq; | |
886 | timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); | 889 | timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); |
887 | 890 | ||
888 | if (dest->addrtype == TIPC_ADDR_MCAST) { | 891 | if (dest->addrtype == TIPC_ADDR_MCAST) { |
@@ -1833,17 +1836,24 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest, | |||
1833 | int destlen, int flags) | 1836 | int destlen, int flags) |
1834 | { | 1837 | { |
1835 | struct sock *sk = sock->sk; | 1838 | struct sock *sk = sock->sk; |
1839 | struct tipc_sock *tsk = tipc_sk(sk); | ||
1836 | struct sockaddr_tipc *dst = (struct sockaddr_tipc *)dest; | 1840 | struct sockaddr_tipc *dst = (struct sockaddr_tipc *)dest; |
1837 | struct msghdr m = {NULL,}; | 1841 | struct msghdr m = {NULL,}; |
1838 | long timeout = (flags & O_NONBLOCK) ? 0 : tipc_sk(sk)->conn_timeout; | 1842 | long timeout = (flags & O_NONBLOCK) ? 0 : tsk->conn_timeout; |
1839 | socket_state previous; | 1843 | socket_state previous; |
1840 | int res; | 1844 | int res = 0; |
1841 | 1845 | ||
1842 | lock_sock(sk); | 1846 | lock_sock(sk); |
1843 | 1847 | ||
1844 | /* For now, TIPC does not allow use of connect() with DGRAM/RDM types */ | 1848 | /* DGRAM/RDM connect(), just save the destaddr */ |
1845 | if (sock->state == SS_READY) { | 1849 | if (sock->state == SS_READY) { |
1846 | res = -EOPNOTSUPP; | 1850 | if (dst->family == AF_UNSPEC) { |
1851 | memset(&tsk->remote, 0, sizeof(struct sockaddr_tipc)); | ||
1852 | tsk->connected = 0; | ||
1853 | } else { | ||
1854 | memcpy(&tsk->remote, dest, destlen); | ||
1855 | tsk->connected = 1; | ||
1856 | } | ||
1847 | goto exit; | 1857 | goto exit; |
1848 | } | 1858 | } |
1849 | 1859 | ||