[rds-commits] jlbec commits r100 - in trunk: . linux/net/rds

svn-commits@oss.oracle.com svn-commits at oss.oracle.com
Wed Jun 7 15:35:05 CDT 2006


Author: jlbec
Date: 2006-06-07 15:35:04 -0500 (Wed, 07 Jun 2006)
New Revision: 100

Modified:
   trunk/TODO
   trunk/linux/net/rds/
   trunk/linux/net/rds/af_rds.c
   trunk/linux/net/rds/rds.h
   trunk/linux/net/rds/send.c
Log:

net/rds: Add connect() and getpeername() support.

Signed-off-by: Joel Becker <joel.becker at oracle.com>



Modified: trunk/TODO
===================================================================
--- trunk/TODO	2006-06-05 20:43:28 UTC (rev 99)
+++ trunk/TODO	2006-06-07 20:35:04 UTC (rev 100)
@@ -12,8 +12,6 @@
 other threads fail.  Maybe we'll want a generic connection managemenet thread,
 too.  the ->send_trigger stuff would turn into some kind of rds_kick_thread() .
 
-connect() should be implemented, too. (don't forget getpeername)
-
 If message headers had more info on their position in the message then
 we could detect framing errors on the receiver more aggressively.  and
 we probably should.  While we're at it, this could clean up the goofy


Property changes on: trunk/linux/net/rds
___________________________________________________________________
Name: svn:ignore
   - *.o.cmd
*.ko.cmd
*.ko
*.mod.c
.tmp_versions
.*.o.d

   + *.o.cmd
*.ko.cmd
*.ko
*.mod.c
.tmp_versions
.*.o.d
Modules.symvers


Modified: trunk/linux/net/rds/af_rds.c
===================================================================
--- trunk/linux/net/rds/af_rds.c	2006-06-05 20:43:28 UTC (rev 99)
+++ trunk/linux/net/rds/af_rds.c	2006-06-07 20:35:04 UTC (rev 100)
@@ -86,13 +86,19 @@
 
 	memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
 
-	if (peer)
-		return -ENOTCONN;
+	/* racey, don't care */
+	if (peer) {
+		if (!rs->rs_conn_addr)
+			return -ENOTCONN;
 
+		sin->sin_port = rs->rs_conn_port;
+		sin->sin_addr.s_addr = rs->rs_conn_addr;
+	} else {
+		sin->sin_port = rs->rs_bound_port;
+		sin->sin_addr.s_addr = rs->rs_bound_addr;
+	}
+
 	sin->sin_family = AF_INET;
-	/* racey, don't care */
-	sin->sin_port = rs->rs_bound_port;
-	sin->sin_addr.s_addr = rs->rs_bound_addr;
 
 	*uaddr_len = sizeof(*sin);
 	return 0;
@@ -227,6 +233,42 @@
 
 }
 
+
+static int rds_connect(struct socket *sock, struct sockaddr *uaddr,
+		       int addr_len, int flags)
+{
+	struct sock *sk = sock->sk;
+	struct sockaddr_in *sin = (struct sockaddr_in *)uaddr;
+	struct rds_sock *rs = rds_sk_to_rs(sk);
+	int ret = 0;
+
+	lock_sock(sk);
+
+	if (addr_len != sizeof(struct sockaddr_in)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (sin->sin_family != AF_INET) {
+		ret = -EAFNOSUPPORT;
+		goto out;
+	}
+
+	if (sin->sin_addr.s_addr == INADDR_ANY) {
+		ret = -EDESTADDRREQ;
+		goto out;
+	}
+
+	rds_debug(rs, "connect sock %p sk %p %u.%u.%u.%u:%u\n", sock, sk,
+		  NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+	rs->rs_conn_addr = sin->sin_addr.s_addr;
+	rs->rs_conn_port = sin->sin_port;
+
+out:
+	release_sock(sk);
+	return ret;
+}
+
 #ifdef KERNEL_HAS_PROTO_REGISTER
 static struct proto rds_proto = {
 	.name	  = "RDS",
@@ -240,7 +282,7 @@
 	.owner =	THIS_MODULE,
 	.release =	rds_release,
 	.bind =		rds_bind,
-	.connect =	sock_no_connect,
+	.connect =	rds_connect,
 	.socketpair =	sock_no_socketpair,
 	.accept =	sock_no_accept,
 	.getname =	rds_getname,

Modified: trunk/linux/net/rds/rds.h
===================================================================
--- trunk/linux/net/rds/rds.h	2006-06-05 20:43:28 UTC (rev 99)
+++ trunk/linux/net/rds/rds.h	2006-06-07 20:35:04 UTC (rev 100)
@@ -158,10 +158,15 @@
 	 */
 	u32			rs_sndbuf;
 
-	/* used for both incoming and outgoing, no INADDR_ANY support. */
+	/*
+	 * bound_addr used for both incoming and outgoing, no INADDR_ANY
+	 * support.
+	 */
 	struct rb_node		rs_bound_node;
 	__le32			rs_bound_addr;
+	__be32			rs_conn_addr;
 	__le16			rs_bound_port;
+	__be16			rs_conn_port;
 
 	struct list_head	rs_flow_list;
 	/* 

Modified: trunk/linux/net/rds/send.c
===================================================================
--- trunk/linux/net/rds/send.c	2006-06-05 20:43:28 UTC (rev 99)
+++ trunk/linux/net/rds/send.c	2006-06-07 20:35:04 UTC (rev 100)
@@ -298,6 +298,8 @@
 	struct sock *sk = sock->sk;
 	struct rds_sock *rs = rds_sk_to_rs(sk);
 	struct sockaddr_in *usin = (struct sockaddr_in *)msg->msg_name;
+	__be32 daddr;
+	__be16 dport;
 	struct rds_message *rm = NULL;
 	struct rds_flow *flow = NULL;
 	unsigned long nr_frags;
@@ -314,15 +316,25 @@
 	else
 		nr_frags = ceil(payload_len, RDS_FRAG_SIZE);
 
-	/* XXX fail non-unicast destination IPs? */
-	if (msg->msg_namelen < sizeof(*usin) || usin->sin_family != AF_INET ||
-	    usin->sin_port == 0) {
-		ret = -EINVAL;
-		goto out;
+	if (msg->msg_namelen) {
+		/* XXX fail non-unicast destination IPs? */
+		if (msg->msg_namelen < sizeof(*usin) || usin->sin_family != AF_INET ||
+		    usin->sin_port == 0) {
+			ret = -EINVAL;
+			goto out;
+		}
+		daddr = usin->sin_addr.s_addr;
+		dport = usin->sin_port;
+	} else {
+		/* We only care about consistency with ->connect() */
+		lock_sock(sk);
+		daddr = rs->rs_conn_addr;
+		dport = rs->rs_conn_port;
+		release_sock(sk);
 	}
 
 	/* racing with another thread binding seems ok here */
-	if (usin == NULL || rs->rs_bound_addr == 0) {
+	if (daddr == 0 || rs->rs_bound_addr == 0) {
 		ret = -ENOTCONN; /* XXX not a great errno */
 		goto out;
 	}
@@ -335,7 +347,7 @@
 	}
 
 	flow = rds_flow_create(rs->rs_bound_addr, rs->rs_bound_port,
-			       usin->sin_addr.s_addr, usin->sin_port,
+			       daddr, dport,
 			       sock->sk->sk_allocation);
 	if (IS_ERR(flow)) {
 		ret = PTR_ERR(flow);
@@ -344,7 +356,7 @@
 	}
 
 	while (!rds_send_queue_rm(flow, rm, nr_frags, rs->rs_bound_port, 
-				  usin->sin_port, &queued)) {
+				  dport, &queued)) {
 		rds_stats_inc(s_send_queue_full);
 		/* XXX make sure this is reasonable */
 		if (payload_len > rs->rs_sndbuf) {
@@ -359,7 +371,7 @@
 		timeo = wait_event_interruptible_timeout(*sk->sk_sleep,
 					rds_send_queue_rm(flow, rm, nr_frags,
 							  rs->rs_bound_port,
-							  usin->sin_port,
+							  dport,
 							  &queued),
 					timeo);
 		pr_debug("sendmsg woke queued %d timeo %ld\n", queued, timeo);




More information about the rds-commits mailing list