Subject: Re: NetBSD-3 NIS-compat getpwnam()/getpwuid iterate entire map [was Re: 3.0 YP lookup latency]
To: Christos Zoulas <christos@zoulas.com>
From: None <jonathan@dsg.stanford.edu>
List: tech-net
Date: 06/21/2006 15:36:53
In message <20060621201934.288DA56539@rebar.astron.com>Christos Zoulas writes

>| Oh... and I noticed a bug in clnt_generic(): for RPC-over-TCP, we
>| disable RFC-896 (Nagle) processing for TCP over IPv4, but not for TCP
>| over IPv6[1].  Makes a grown man cry.
>
>And something like this?

[...]

Thanks to Charles for observing that the strncmp() below acutally
matches both "inet" and "inet6", so the bug I feared doesn't
exist. Thus no pullups are needed.

I am still very peturbed by the XXX comment. If someone like fvdl
doesn't grok why the setsockopt() is needed, we need a better
explanation. And I'm worried by both the dependency on the strncmp()
matching both "inet" and "inet6", when what's really meant is
	"are we running over TCP"?

So about something like this:


Index: src/lib/libc/rpc/clnt_generic.c
===================================================================
RCS file: /cvsroot/src/lib/libc/rpc/clnt_generic.c,v
retrieving revision 1.25
diff -u -r1.25 clnt_generic.c
--- src/lib/libc/rpc/clnt_generic.c	2 Dec 2005 12:19:16 -0000	1.25
+++ src/lib/libc/rpc/clnt_generic.c	21 Jun 2006 22:14:03 -0000
@@ -333,8 +333,17 @@
 		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)
+		/*
+		 * 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?
+		 */
+		if (strcmp(nconf->nc_proto, "tcp", (size_t)3) == 0)
 			setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one,
 			    (socklen_t)sizeof (one));
 		break;