summaryrefslogtreecommitdiffstats
path: root/lib/libc/rpc/clnt_udp.c
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>1995-04-02 20:05:20 +0000
committerwpaul <wpaul@FreeBSD.org>1995-04-02 20:05:20 +0000
commit9b1ee02f17b3c5ae7f49fee4faac4177232976b5 (patch)
treebabdb52e19adaa1a0aa648e3dbc5837de034e151 /lib/libc/rpc/clnt_udp.c
parentf49687c8a49f95e856b43515877ec61dff48cc59 (diff)
downloadFreeBSD-src-9b1ee02f17b3c5ae7f49fee4faac4177232976b5.zip
FreeBSD-src-9b1ee02f17b3c5ae7f49fee4faac4177232976b5.tar.gz
Submitted by: Sebastian Strollow
Obtained from: Casper H. Dik (by vay of Usenet) Small patch to help improve NIS rebinding times (among other things): >From: casper@fwi.uva.nl (Casper H.S. Dik) >Newsgroups: comp.sys.sun.misc,comp.sys.sun.admin >Subject: FIX for slow rebinding of NIS. >Summary: a small change in libc makes life with NIS a lot easier. >Message-ID: <1992Jan17.173905.11727@fwi.uva.nl> >Date: 17 Jan 92 17:39:05 GMT >Sender: news@fwi.uva.nl >Organization: FWI, University of Amsterdam >Lines: 138 >Nntp-Posting-Host: halo.fwi.uva.nl Have you been plagued by long waits when your NIS server is rebooted? READ ON! Sun has a patch, but the README says: ********************* WARNING ****************************** This is a new version of ypbind that never uses the NIS binding file to cache the servers binding. This will have the effect of fixing the current symptom. However, it might degrade the overall performance of the system when the server is available. This is most likely to happen on an overloaded server, which will cause the network to produce a broadcast storm. ************************************************************* Therefor, I have produced another fix. o What goes wrong. When the NIS server is rebooted, ypserv will obtain different ports to listen for RPC requests. All clients will continue to use the old binding they obtained earlier. The NIS server will send ICMP dst unreachable messages for the RPC requests that arrive at the old port. These ICMPs are dropped on the floor and the client code will continue sending the requests until the timer has expired. The small fix at the end of this message will pick up these ICMP messages and deliver them to the RPC layer. o Before and after. I've tested this on some machines and this is the result: (kill and restart ypserv on the server) original% time ypmatch user passwd user:.... 0.040u 0.090s 2:35.64 0.0% 0+126k 0+0io 0pf+0w (155 seconds elapsed time) fixedhost% time ypmatch user passwd user:.... 0.050u 0.050s 0:10.20 0.9% 0+136k 0+0io 0pf+0w (10 seconds elapsed time) Rebinding is almost instantaneous. o Other benefits. RPC calls that use UDP as transport will no longer time out but will abort much sooner. (E.g., the remote host is unreachable or 111/udp is filtered by an intermediate router)
Diffstat (limited to 'lib/libc/rpc/clnt_udp.c')
-rw-r--r--lib/libc/rpc/clnt_udp.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/lib/libc/rpc/clnt_udp.c b/lib/libc/rpc/clnt_udp.c
index 4df4631..42dfcf1 100644
--- a/lib/libc/rpc/clnt_udp.c
+++ b/lib/libc/rpc/clnt_udp.c
@@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)clnt_udp.c 2.2 88/08/01 4.0 RPCSRC";*/
-static char *rcsid = "$Id: clnt_udp.c,v 1.1 1993/10/27 05:40:25 paul Exp $";
+static char *rcsid = "$Id: clnt_udp.c,v 1.1 1994/08/07 18:35:48 wollman Exp $";
#endif
/*
@@ -258,10 +258,20 @@ call_again:
return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
outlen = (int)XDR_GETPOS(xdrs);
+ /*
+ * Give error (ECONNREFUSED/EHOSTUNREACH) instead of timeout.
+ * Gives much faster NIS rebinding.
+ * Errors are not detected here, but in the recvfrom()
+ * following the select().
+ */
+ if (connect(cu->cu_sock, (struct sockaddr *)(&cu->cu_raddr),
+ cu->cu_rlen) != 0) {
+ cu->cu_error.re_errno = errno;
+ return (cu->cu_error.re_status = RPC_CANTSEND);
+ }
+
send_again:
- if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,
- (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen)
- != outlen) {
+ if (send(cu->cu_sock, cu->cu_outbuf, outlen, 0) != outlen) {
cu->cu_error.re_errno = errno;
return (cu->cu_error.re_status = RPC_CANTSEND);
}
OpenPOWER on IntegriCloud