From 8eff4cb820e0a756ecb7e2f1281122c030398010 Mon Sep 17 00:00:00 2001 From: wpaul Date: Tue, 7 Jan 1997 06:07:21 +0000 Subject: yp_server.c: - Fail YPPROC_ALL requests when we hit the child process limit. This is a little harsh, but it helps prevent the parent from blocking and causing other requests to time out. yp_dnslookup.c: - Check for duplicate RPC transaction IDs that indicate duplicate requests sent due to RPC retransmissions. We don't want to send a second DNS request for the same data while an existing request is in progress. - Fix small formatting bogon in snprintf() in yp_async_lookup_addr(). --- usr.sbin/ypserv/yp_dnslookup.c | 61 +++++++++++++++++++++++++++++++----------- usr.sbin/ypserv/yp_server.c | 12 ++++++++- 2 files changed, 56 insertions(+), 17 deletions(-) (limited to 'usr.sbin/ypserv') diff --git a/usr.sbin/ypserv/yp_dnslookup.c b/usr.sbin/ypserv/yp_dnslookup.c index 91eebc3..b64bbcf 100644 --- a/usr.sbin/ypserv/yp_dnslookup.c +++ b/usr.sbin/ypserv/yp_dnslookup.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: yp_dnslookup.c,v 1.9 1996/12/25 17:52:35 wpaul Exp $ + * $Id: yp_dnslookup.c,v 1.13 1997/01/07 04:48:52 wpaul Exp $ */ /* @@ -65,7 +65,7 @@ #include "yp_extern.h" #ifndef lint -static const char rcsid[] = "$Id: yp_dnslookup.c,v 1.9 1996/12/25 17:52:35 wpaul Exp $"; +static const char rcsid[] = "$Id: yp_dnslookup.c,v 1.13 1997/01/07 04:48:52 wpaul Exp $"; #endif static char *parse(hp) @@ -98,6 +98,9 @@ static char *parse(hp) #define MAXPACKET 1024 #define DEF_TTL 50 +#define BY_DNS_ID 1 +#define BY_RPC_XID 2 + extern struct hostent *__dns_getanswer __P((char *, int, char *, int)); static CIRCLEQ_HEAD(dns_qhead, circleq_dnsentry) qhead; @@ -191,14 +194,24 @@ static unsigned long yp_send_dns_query(name, type) return(id); } -static struct circleq_dnsentry *yp_find_dnsqent(id) +static struct circleq_dnsentry *yp_find_dnsqent(id, type) unsigned long id; + int type; { register struct circleq_dnsentry *q; for (q = qhead.cqh_first; q != (void *)&qhead; q = q->links.cqe_next) { - if (id == q->id) - return(q); + switch(type) { + case BY_RPC_XID: + if (id == q->xid) + return(q); + break; + case BY_DNS_ID: + default: + if (id == q->id) + return(q); + break; + } } return (NULL); } @@ -357,7 +370,8 @@ void yp_run_dnsq() * on the floor. */ hptr = (HEADER *)&buf; - if (!pending || (q = yp_find_dnsqent(ntohs(hptr->id))) == NULL) { + if (!pending || + (q = yp_find_dnsqent(ntohs(hptr->id), BY_DNS_ID)) == NULL) { /* ignore */ return; } @@ -413,6 +427,18 @@ ypstat yp_async_lookup_name(rqstp, name) register struct circleq_dnsentry *q; int type, len; + /* Check for SOCK_DGRAM or SOCK_STREAM -- we need to know later */ + if (getsockopt(rqstp->rq_xprt->xp_sock, SOL_SOCKET, + SO_TYPE, &type, &len) == -1) { + yp_error("getsockopt failed: %s", strerror(errno)); + return(YP_YPERR); + } + + /* Avoid transmitting dupe requests. */ + if (type == SOCK_DGRAM && + yp_find_dnsqent(svcudp_get_xid(rqstp->rq_xprt),BY_RPC_XID) != NULL) + return(YP_TRUE); + if ((q = yp_malloc_dnsent()) == NULL) return(YP_YPERR); @@ -421,10 +447,6 @@ ypstat yp_async_lookup_name(rqstp, name) q->xprt = rqstp->rq_xprt; q->ypvers = rqstp->rq_vers; type = -1; len = sizeof(type); - if (getsockopt(q->xprt->xp_sock,SOL_SOCKET,SO_TYPE,&type,&len) == -1) { - yp_error("getsockopt failed: %s", strerror(errno)); - return(YP_YPERR); - } q->prot_type = type; if (q->prot_type == SOCK_DGRAM) q->xid = svcudp_get_xid(q->xprt); @@ -463,14 +485,25 @@ ypstat yp_async_lookup_addr(rqstp, addr) int a, b, c, d; int type, len; + /* Check for SOCK_DGRAM or SOCK_STREAM -- we need to know later */ + if (getsockopt(rqstp->rq_xprt->xp_sock, SOL_SOCKET, + SO_TYPE, &type, &len) == -1) { + yp_error("getsockopt failed: %s", strerror(errno)); + return(YP_YPERR); + } + + /* Avoid transmitting dupe requests. */ + if (type == SOCK_DGRAM && + yp_find_dnsqent(svcudp_get_xid(rqstp->rq_xprt),BY_RPC_XID) != NULL) + return(YP_TRUE); + if ((q = yp_malloc_dnsent()) == NULL) return(YP_YPERR); if (sscanf(addr, "%d.%d.%d.%d", &a, &b, &c, &d) != 4) return(YP_NOKEY); - snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa", - d, c, b, a, addr); + snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa", d, c, b, a); if (debug) yp_error("DNS address is: %s", buf); @@ -481,10 +514,6 @@ ypstat yp_async_lookup_addr(rqstp, addr) q->ypvers = rqstp->rq_vers; q->domain = NULL; type = -1; len = sizeof(type); - if (getsockopt(q->xprt->xp_sock,SOL_SOCKET,SO_TYPE,&type,&len) == -1) { - yp_error("getsockopt failed: %s", strerror(errno)); - return(YP_YPERR); - } q->prot_type = type; if (q->prot_type == SOCK_DGRAM) q->xid = svcudp_get_xid(q->xprt); diff --git a/usr.sbin/ypserv/yp_server.c b/usr.sbin/ypserv/yp_server.c index da1a73b..8d9c19c 100644 --- a/usr.sbin/ypserv/yp_server.c +++ b/usr.sbin/ypserv/yp_server.c @@ -45,7 +45,7 @@ #include #ifndef lint -static const char rcsid[] = "$Id: yp_server.c,v 1.3 1996/12/24 18:43:53 wpaul Exp $"; +static const char rcsid[] = "$Id: yp_server.c,v 1.4 1997/01/07 04:10:51 wpaul Exp $"; #endif /* not lint */ int forked = 0; @@ -466,6 +466,16 @@ ypproc_all_2_svc(ypreq_nokey *argp, struct svc_req *rqstp) } /* + * XXX If we hit the child limit, fail the request. + * If we don't, and the map is large, we could block for + * a long time in the parent. + */ + if (children >= MAX_CHILDREN) { + result.ypresp_all_u.val.stat = YP_YPERR; + return(&result); + } + + /* * The ypproc_all procedure can take a while to complete. * Best to handle it in a subprocess so the parent doesn't * block. (Is there a better way to do this? Maybe with -- cgit v1.1