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:
parent
f6d914e806
commit
e029a91736
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user