Subject: Re: NetBSD-3 NIS-compat getpwnam()/getpwuid iterate entire map [was Re: 3.0 YP lookup latency]
To: Charles M. Hannum <mycroft@MIT.EDU>
From: Christos Zoulas <christos@zoulas.com>
List: tech-net
Date: 06/22/2006 13:28:02
On Jun 22,  1:05pm, mycroft@MIT.EDU ("Charles M. Hannum") wrote:
-- Subject: Re: NetBSD-3 NIS-compat getpwnam()/getpwuid iterate entire map [w

| FTR, I'm not really a fan of this use of strncmp().  OTOH, your
| suggestion assumes there will never be an incompatible protocol named
| "TCP" in another protocol family.  Is this a safe assumption?  Who
| knows.  I think it's better to test the protocol family *and* protocol
| if you're trying to be "careful".

How about this?

christos

Index: clnt_generic.c
===================================================================
RCS file: /cvsroot/src/lib/libc/rpc/clnt_generic.c,v
retrieving revision 1.25
diff -u -u -r1.25 clnt_generic.c
--- clnt_generic.c	2 Dec 2005 12:19:16 -0000	1.25
+++ clnt_generic.c	22 Jun 2006 17:26:45 -0000
@@ -289,7 +289,6 @@
 	CLIENT *cl;			/* client handle */
 	bool_t madefd = FALSE;		/* whether fd opened here */
 	long servtype;
-	int one = 1;
 	struct __rpc_sockinfo si;
 
 	/* nconf is handled below */
@@ -333,10 +332,8 @@
 		cl = clnt_vc_create(fd, svcaddr, prog, vers, sendsz, recvsz);
 		if (!nconf || !cl)
 			break;
-		/* XXX fvdl - is this useful? */
-		if (strncmp(nconf->nc_protofmly, "inet", (size_t)4) == 0)
-			setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one,
-			    (socklen_t)sizeof (one));
+		if (si.si_proto == IPPROTO_TCP)
+			__rpc_setnodelay(fd);
 		break;
 	case NC_TPI_CLTS:
 		cl = clnt_dg_create(fd, svcaddr, prog, vers, sendsz, recvsz);
Index: rpc_generic.c
===================================================================
RCS file: /cvsroot/src/lib/libc/rpc/rpc_generic.c,v
retrieving revision 1.21
diff -u -u -r1.21 rpc_generic.c
--- rpc_generic.c	19 Mar 2006 01:43:11 -0000	1.21
+++ rpc_generic.c	22 Jun 2006 17:26:45 -0000
@@ -873,3 +873,20 @@
 
 	return 0;
 }
+
+/*
+ * For TCP transport, Host Requirements RFCs mandate
+ * Nagle (RFC-896) processing.  But for RPC, Nagle
+ * processing adds adds unwanted latency to the last,
+ * partial TCP segment of each RPC message. See:
+ *   R. W. Scheifler and J. Gettys, The X Window System,
+ *   ACM Transactions on Graphics 16:8 (Aug. 1983), pp. 57-69. 
+ * So for TCP transport, disable Nagle via TCP_NODELAY.
+ * XXX: moral equivalent for non-TCP protocols?
+ */
+int
+__rpc_setnodelay(int fd)
+{
+	int one = 1;
+	return setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
+}
Index: svc_vc.c
===================================================================
RCS file: /cvsroot/src/lib/libc/rpc/svc_vc.c,v
retrieving revision 1.18
diff -u -u -r1.18 svc_vc.c
--- svc_vc.c	22 Mar 2006 12:51:32 -0000	1.18
+++ svc_vc.c	22 Jun 2006 17:26:45 -0000
@@ -356,11 +356,8 @@
 		newxprt->xp_addrlen = sizeof (struct sockaddr_in);
 	}
 #endif
-	if (__rpc_fd2sockinfo(sock, &si) && si.si_proto == IPPROTO_TCP) {
-		len = 1;
-		/* XXX fvdl - is this useful? */
-		setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &len, sizeof (len));
-	}
+	if (__rpc_fd2sockinfo(sock, &si) && si.si_proto == IPPROTO_TCP)
+		__rpc_setnodelay(sock);
 
 	cd = (struct cf_conn *)newxprt->xp_p1;