summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ypserv
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>1997-01-07 06:07:21 +0000
committerwpaul <wpaul@FreeBSD.org>1997-01-07 06:07:21 +0000
commit8eff4cb820e0a756ecb7e2f1281122c030398010 (patch)
tree7a7afa6fdb2e644fa7a46cf1b953fbc301d3df1f /usr.sbin/ypserv
parentb5b43871ac9e5f78455d5b87d8267d857ab4a9a1 (diff)
downloadFreeBSD-src-8eff4cb820e0a756ecb7e2f1281122c030398010.zip
FreeBSD-src-8eff4cb820e0a756ecb7e2f1281122c030398010.tar.gz
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().
Diffstat (limited to 'usr.sbin/ypserv')
-rw-r--r--usr.sbin/ypserv/yp_dnslookup.c61
-rw-r--r--usr.sbin/ypserv/yp_server.c12
2 files changed, 56 insertions, 17 deletions
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 <rpc/rpc.h>
#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
OpenPOWER on IntegriCloud