diff options
author | Ulrich Drepper <drepper@redhat.com> | 2002-10-17 21:51:21 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2002-10-17 21:51:21 +0000 |
commit | 0420d8885a4889dca3b874c934fd5f42f2e99e5f (patch) | |
tree | dd8aecefe9a5f21d26df11cbc7f9c1dc6f2f5fd9 /resolv/res_send.c | |
parent | d025fe269abcab6903b3973d193a8678228301e8 (diff) | |
download | glibc-0420d8885a4889dca3b874c934fd5f42f2e99e5f.zip glibc-0420d8885a4889dca3b874c934fd5f42f2e99e5f.tar.gz glibc-0420d8885a4889dca3b874c934fd5f42f2e99e5f.tar.bz2 |
Update.
2002-10-15 Jakub Jelinek <jakub@redhat.com>
* include/resolv.h (__libc_res_nquery, __libc_res_nsearch,
__libc_res_nsend): New prototypes.
* resolv/res_query.c (QUERYSIZE): Define.
(__libc_res_nquery): Renamed from res_nquery. Added answerp
argument. Allocate only QUERYSIZE bytes first, if res_nmkquery
fails use MAXPACKET buffer. Call __libc_res_nsend instead of
res_nsend, pass answerp.
(res_nquery): Changed into wrapper around __libc_res_nquery.
(__libc_res_nsearch): Renamed from res_nsearch. Added answerp
argument. Call __libc_res_nquerydomain and __libc_res_nquery
instead of the non-__libc_ variants, pass them answerp.
(res_nsearch): Changed into wrapper around __libc_res_nsearch.
(__libc_res_nquerydomain): Renamed from res_nquerydomain.
Added answerp argument. Call __libc_res_nquery instead of
res_nquery, pass answerp.
(res_nquerydomain): Changed into wrapper around
__libc_res_nquerydomain.
* resolv/res_send.c: Include sys/ioctl.h.
(MAXPACKET): Define.
(send_vc): Change arguments. Reallocate answer buffer if it is
too small.
(send_dg): Likewise.
(__libc_res_nsend): Renamed from res_nsend. Added ansp argument.
Reallocate answer buffer if it is too small and hooks are in use.
Adjust calls to send_vc and send_dg.
(res_nsend): Changed into wrapper around __libc_res_nsend.
* resolv/nss_dns/dns-host.c (_nss_dns_gethostbyname2_r): Allocate
just 1K answer buffer on the stack, use __libc_res_nsearch instead
of res_nsearch.
(_nss_dns_gethostbyaddr_r): Similarly with __libc_res_nquery.
* resolv/nss_dns/dns-network.c (_nss_dns_getnetbyaddr_r): Likewise.
(_nss_dns_getnetbyname_r): Similarly with __libc_res_nsearch.
* resolv/gethnamaddr.c (gethostbyname2): Likewise.
(gethostbyaddr): Similarly with __libc_res_nquery.
* resolv/Versions (libresolv): Export __libc_res_nquery and
__libc_res_nsearch at GLIBC_PRIVATE.
Diffstat (limited to 'resolv/res_send.c')
-rw-r--r-- | resolv/res_send.c | 96 |
1 files changed, 78 insertions, 18 deletions
diff --git a/resolv/res_send.c b/resolv/res_send.c index a163d06..d237c9a 100644 --- a/resolv/res_send.c +++ b/resolv/res_send.c @@ -85,6 +85,7 @@ static const char rcsid[] = "$BINDId: res_send.c,v 8.38 2000/03/30 20:16:51 vixi #include <netinet/in.h> #include <arpa/nameser.h> #include <arpa/inet.h> +#include <sys/ioctl.h> #include <errno.h> #include <netdb.h> @@ -95,6 +96,12 @@ static const char rcsid[] = "$BINDId: res_send.c,v 8.38 2000/03/30 20:16:51 vixi #include <string.h> #include <unistd.h> +#if PACKETSZ > 65536 +#define MAXPACKET PACKETSZ +#else +#define MAXPACKET 65536 +#endif + #ifndef _LIBC #include <isc/eventlib.h> #else @@ -193,10 +200,10 @@ static const int highestFD = FD_SETSIZE - 1; /* Forward. */ static int send_vc(res_state, const u_char *, int, - u_char *, int, int *, int); + u_char **, int *, int *, int, u_char **); static int send_dg(res_state, const u_char *, int, - u_char *, int, int *, int, - int *, int *); + u_char **, int *, int *, int, + int *, int *, u_char **); #ifdef DEBUG static void Aerror(const res_state, FILE *, const char *, int, struct sockaddr_in); @@ -371,8 +378,8 @@ res_queriesmatch(const u_char *buf1, const u_char *eom1, } int -res_nsend(res_state statp, - const u_char *buf, int buflen, u_char *ans, int anssiz) +__libc_res_nsend(res_state statp, const u_char *buf, int buflen, + u_char *ans, int anssiz, u_char **ansp) { int gotsomewhere, terrno, try, v_circuit, resplen, ns, n; @@ -380,10 +387,22 @@ res_nsend(res_state statp, __set_errno (ESRCH); return (-1); } + if (anssiz < HFIXEDSZ) { __set_errno (EINVAL); return (-1); } + + if ((statp->qhook || statp->rhook) && anssiz < MAXPACKET && ansp) { + u_char *buf = malloc (MAXPACKET); + if (buf == NULL) + return (-1); + memcpy (buf, ans, HFIXEDSZ); + *ansp = buf; + ans = buf; + anssiz = MAXPACKET; + } + DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_QUERY), (stdout, ";; res_send()\n"), buf, buflen); v_circuit = (statp->options & RES_USEVC) || buflen > PACKETSZ; @@ -578,8 +597,8 @@ res_nsend(res_state statp, if (v_circuit) { /* Use VC; at most one attempt per server. */ try = statp->retry; - n = send_vc(statp, buf, buflen, ans, anssiz, &terrno, - ns); + n = send_vc(statp, buf, buflen, &ans, &anssiz, &terrno, + ns, ansp); if (n < 0) return (-1); if (n == 0) @@ -587,8 +606,8 @@ res_nsend(res_state statp, resplen = n; } else { /* Use datagrams. */ - n = send_dg(statp, buf, buflen, ans, anssiz, &terrno, - ns, &v_circuit, &gotsomewhere); + n = send_dg(statp, buf, buflen, &ans, &anssiz, &terrno, + ns, &v_circuit, &gotsomewhere, ansp); if (n < 0) return (-1); if (n == 0) @@ -667,14 +686,23 @@ res_nsend(res_state statp, return (-1); } +int +res_nsend(res_state statp, + const u_char *buf, int buflen, u_char *ans, int anssiz) +{ + return __libc_res_nsend(statp, buf, buflen, ans, anssiz, NULL); +} + /* Private */ static int send_vc(res_state statp, - const u_char *buf, int buflen, u_char *ans, int anssiz, - int *terrno, int ns) + const u_char *buf, int buflen, u_char **ansp, int *anssizp, + int *terrno, int ns, u_char **anscp) { const HEADER *hp = (HEADER *) buf; + u_char *ans = *ansp; + int anssiz = *anssizp; HEADER *anhp = (HEADER *) ans; #ifdef _LIBC struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns]; @@ -782,11 +810,26 @@ send_vc(res_state statp, } resplen = ns_get16(ans); if (resplen > anssiz) { - Dprint(statp->options & RES_DEBUG, - (stdout, ";; response truncated\n") - ); - truncating = 1; - len = anssiz; + if (anscp) { + ans = malloc (MAXPACKET); + if (ans == NULL) { + *terrno = ENOMEM; + res_nclose(statp); + return (0); + } + anssiz = MAXPACKET; + *anssizp = MAXPACKET; + *ansp = ans; + *anscp = ans; + anhp = (HEADER *) ans; + len = resplen; + } else { + Dprint(statp->options & RES_DEBUG, + (stdout, ";; response truncated\n") + ); + truncating = 1; + len = anssiz; + } } else len = resplen; if (len < HFIXEDSZ) { @@ -851,10 +894,12 @@ send_vc(res_state statp, static int send_dg(res_state statp, - const u_char *buf, int buflen, u_char *ans, int anssiz, - int *terrno, int ns, int *v_circuit, int *gotsomewhere) + const u_char *buf, int buflen, u_char **ansp, int *anssizp, + int *terrno, int ns, int *v_circuit, int *gotsomewhere, u_char **anscp) { const HEADER *hp = (HEADER *) buf; + u_char *ans = *ansp; + int anssiz = *anssizp; HEADER *anhp = (HEADER *) ans; #ifdef _LIBC struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns]; @@ -992,6 +1037,21 @@ send_dg(res_state statp, #else fromlen = sizeof(struct sockaddr_in); #endif + if (anssiz < MAXPACKET + && anscp + && (ioctl (s, FIONREAD, &resplen) < 0 + || anssiz < resplen)) { + ans = malloc (MAXPACKET); + if (ans == NULL) + ans = *ansp; + else { + anssiz = MAXPACKET; + *anssizp = MAXPACKET; + *ansp = ans; + *anscp = ans; + anhp = (HEADER *) ans; + } + } resplen = recvfrom(s, (char*)ans, anssiz,0, (struct sockaddr *)&from, &fromlen); if (resplen <= 0) { |