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().
This commit is contained in:
wpaul 1997-01-07 06:07:21 +00:00
parent f6d914e806
commit e029a91736
2 changed files with 56 additions and 17 deletions

View File

@ -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);

View File

@ -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;
@ -465,6 +465,16 @@ ypproc_all_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
return (&result);
}
/*
* 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