aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorErik Hugne <erik.hugne@ericsson.com>2015-03-19 04:02:19 -0400
committerDavid S. Miller <davem@davemloft.net>2015-03-19 12:25:54 -0400
commitf2f8036e391eb82ee78764483f869f2feafb5da8 (patch)
treeaebead12cc0faf722ad62b94826730754830dd1b /net/tipc
parent3bd88ee7a2ea19dffe384e12fe452c59d9e53c29 (diff)
tipc: add support for connect() on dgram/rdm sockets
Following the example of ip4_datagram_connect, we store the address in the socket structure for dgram/rdm sockets and use that as the default destination for subsequent send() calls. It is allowed to connect to any address types, and the behaviour of send() will be the same as a normal sendto() with this address provided. Binding to an AF_UNSPEC address clears the association. Signed-off-by: Erik Hugne <erik.hugne@ericsson.com> Reviewed-by: Ying Xue <ying.xue@windriver.com> Reviewed-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/socket.c38
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