diff options
author | peter <peter@FreeBSD.org> | 1995-08-20 20:03:06 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1995-08-20 20:03:06 +0000 |
commit | bbe6ab41603ea223c7c921bd48586ed795917870 (patch) | |
tree | 32821775fcd4108257c3d49593dadeb5a5f18b17 /lib/libc/net/res_send.c | |
parent | 2dd1919d1c22bd3dc75ab1064352572d401b1ab9 (diff) | |
download | FreeBSD-src-bbe6ab41603ea223c7c921bd48586ed795917870.zip FreeBSD-src-bbe6ab41603ea223c7c921bd48586ed795917870.tar.gz |
Update the resolver part of libc to bind-4.9.3-beta24 level (from beta9p1)
Note that this was done by selective patching from diffs, to not conflict
with the 4.4bsd base code.. This was *not* a trivial task.. I have been
testing this code (apart from cosmetic changes) in my libc for a while now.
Obtained from: Paul Vixie <paul@vix.com>
Diffstat (limited to 'lib/libc/net/res_send.c')
-rw-r--r-- | lib/libc/net/res_send.c | 142 |
1 files changed, 72 insertions, 70 deletions
diff --git a/lib/libc/net/res_send.c b/lib/libc/net/res_send.c index 8ee0a92..d5c9c28 100644 --- a/lib/libc/net/res_send.c +++ b/lib/libc/net/res_send.c @@ -53,7 +53,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: res_send.c,v 1.3 1994/09/25 17:45:41 pst Exp $"; +static char rcsid[] = "$Id: res_send.c,v 1.4 1995/05/30 05:40:58 rgrimes Exp $"; #endif /* LIBC_SCCS and not lint */ /* change this to "0" @@ -61,7 +61,7 @@ static char rcsid[] = "$Id: res_send.c,v 1.3 1994/09/25 17:45:41 pst Exp $"; * of multi-homed SunOS * ("broken") name servers. */ -#define CHECK_SRVR_ADDR 1 /* XXX - should be in options.h */ +#define CHECK_SRVR_ADDR 1 /* XXX - should be in res_config.h */ /* * Send query to name server and wait for reply. @@ -78,8 +78,12 @@ static char rcsid[] = "$Id: res_send.c,v 1.3 1994/09/25 17:45:41 pst Exp $"; #include <stdio.h> #include <errno.h> #include <resolv.h> +#include <netdb.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> + +#include <res_config.h> void _res_close __P((void)); @@ -87,12 +91,17 @@ static int s = -1; /* socket used for communications */ static int connected = 0; /* is the socket connected */ static int vc = 0; /* is the socket a virtual ciruit? */ +#ifndef DEBUG +# define Dprint(cond, args) /*empty*/ +# define DprintQ(cond, args, query, size) /*empty*/ +# define Aerror(file, string, error, address) /*empty*/ +# define Perror(file, string, error) /*empty*/ +#else # define Dprint(cond, args) if (cond) {fprintf args;} else {} -# define DprintQ(cond, args, query) if (cond) {\ +# define DprintQ(cond, args, query, size) if (cond) {\ fprintf args;\ - __p_query(query);\ + __fp_nquery(query, size, stdout);\ } else {} - static void Aerror(file, string, error, address) FILE *file; @@ -103,15 +112,14 @@ Aerror(file, string, error, address) int save = errno; if (_res.options & RES_DEBUG) { - fprintf(file, "res_send: %s ([%s].%d): %s\n", + fprintf(file, "res_send: %s ([%s].%u): %s\n", string, inet_ntoa(address.sin_addr), - address.sin_port, + ntohs(address.sin_port), strerror(error)); } errno = save; } - static void Perror(file, string, error) FILE *file; @@ -126,6 +134,7 @@ Perror(file, string, error) } errno = save; } +#endif static res_send_qhook Qhook = NULL; static res_send_rhook Rhook = NULL; @@ -134,6 +143,7 @@ void res_send_setqhook(hook) res_send_qhook hook; { + Qhook = hook; } @@ -141,11 +151,12 @@ void res_send_setrhook(hook) res_send_rhook hook; { + Rhook = hook; } /* int - * our_server(ina) + * res_isourserver(ina) * looks up "ina" in _res.ns_addr_list[] * returns: * 0 : not found @@ -153,8 +164,8 @@ res_send_setrhook(hook) * author: * paul vixie, 29may94 */ -static int -our_server(inp) +int +res_isourserver(inp) const struct sockaddr_in *inp; { struct sockaddr_in ina; @@ -177,15 +188,17 @@ our_server(inp) } /* int - * name_in_query(name, type, class, buf, eom) + * res_nameinquery(name, type, class, buf, eom) * look for (name,type,class) in the query section of packet (buf,eom) * returns: * -1 : format error * 0 : not found * >0 : found + * author: + * paul vixie, 29may94 */ -static int -name_in_query(name, type, class, buf, eom) +int +res_nameinquery(name, type, class, buf, eom) const char *name; register int type, class; const u_char *buf, *eom; @@ -212,16 +225,18 @@ name_in_query(name, type, class, buf, eom) } /* int - * queries_match(buf1, eom1, buf2, eom2) + * res_queriesmatch(buf1, eom1, buf2, eom2) * is there a 1:1 mapping of (name,type,class) * in (buf1,eom1) and (buf2,eom2)? * returns: * -1 : format error * 0 : not a 1:1 mapping * >0 : is a 1:1 mapping + * author: + * paul vixie, 29may94 */ -static int -queries_match(buf1, eom1, buf2, eom2) +int +res_queriesmatch(buf1, eom1, buf2, eom2) const u_char *buf1, *eom1; const u_char *buf2, *eom2; { @@ -240,7 +255,7 @@ queries_match(buf1, eom1, buf2, eom2) cp += n; ttype = _getshort(cp); cp += INT16SZ; tclass = _getshort(cp); cp += INT16SZ; - if (!name_in_query(tname, ttype, tclass, buf2, eom2)) + if (!res_nameinquery(tname, ttype, tclass, buf2, eom2)) return (0); } return (1); @@ -255,21 +270,20 @@ res_send(buf, buflen, ans, anssiz) { HEADER *hp = (HEADER *) buf; HEADER *anhp = (HEADER *) ans; - int gotsomewhere = 0, - connreset = 0, - terrno = ETIMEDOUT; - + int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns; register int n; - int try, v_circuit, resplen, ns; u_int badns; /* XXX NSMAX can't exceed #/bits in this var */ - DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY), - (stdout, ";; res_send()\n"), buf); - if (!(_res.options & RES_INIT)) { - if (res_init() == -1) + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + /* errno should have been set by res_init() in this case. */ return (-1); } + DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY), + (stdout, ";; res_send()\n"), buf, buflen); v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ; + gotsomewhere = 0; + connreset = 0; + terrno = ETIMEDOUT; badns = 0; /* @@ -290,12 +304,8 @@ res_send(buf, buflen, ans, anssiz) do { res_sendhookact act; - act = (*Qhook)(&nsap, - &buf, - &buflen, - ans, - anssiz, - &resplen); + act = (*Qhook)(&nsap, &buf, &buflen, + ans, anssiz, &resplen); switch (act) { case res_goahead: done = 1; @@ -338,16 +348,15 @@ res_send(buf, buflen, ans, anssiz) if (s >= 0) _res_close(); - s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC); + s = socket(PF_INET, SOCK_STREAM, 0); if (s < 0) { terrno = errno; Perror(stderr, "socket(vc)", errno); return (-1); } - if (connect(s, - (struct sockaddr *)nsap, - sizeof(struct sockaddr)) - < 0) { + errno = 0; + if (connect(s, (struct sockaddr *)nsap, + sizeof(struct sockaddr)) < 0) { terrno = errno; Aerror(stderr, "connect/vc", errno, *nsap); @@ -414,8 +423,7 @@ res_send(buf, buflen, ans, anssiz) len = resplen; cp = ans; while (len != 0 && - (n = read(s, (char *)cp, (int)len)) > 0 - ) { + (n = read(s, (char *)cp, (int)len)) > 0) { cp += n; len -= n; } @@ -433,7 +441,7 @@ res_send(buf, buflen, ans, anssiz) anhp->tc = 1; len = resplen - anssiz; while (len != 0) { - char junk[512]; + char junk[PACKETSZ]; n = (len > sizeof(junk) ? sizeof(junk) @@ -456,9 +464,9 @@ res_send(buf, buflen, ans, anssiz) if ((s < 0) || vc) { if (vc) _res_close(); - s = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC); + s = socket(PF_INET, SOCK_DGRAM, 0); if (s < 0) { - bad_dg_sock: terrno = errno; + terrno = errno; Perror(stderr, "socket(dg)", errno); return (-1); } @@ -485,11 +493,9 @@ res_send(buf, buflen, ans, anssiz) * receive a response from another server. */ if (!connected) { - if (connect(s, - (struct sockaddr *)nsap, + if (connect(s, (struct sockaddr *)nsap, sizeof(struct sockaddr) - ) < 0 - ) { + ) < 0) { Aerror(stderr, "connect(dg)", errno, *nsap); @@ -499,7 +505,7 @@ res_send(buf, buflen, ans, anssiz) } connected = 1; } - if (send(s, buf, buflen, 0) != buflen) { + if (send(s, (char*)buf, buflen, 0) != buflen) { Perror(stderr, "send", errno); badns |= (1<<ns); _res_close(); @@ -523,7 +529,7 @@ res_send(buf, buflen, ans, anssiz) connected = 0; errno = 0; } - if (sendto(s, buf, buflen, 0, + if (sendto(s, (char*)buf, buflen, 0, (struct sockaddr *)nsap, sizeof(struct sockaddr)) != buflen) { @@ -558,14 +564,14 @@ res_send(buf, buflen, ans, anssiz) * timeout */ Dprint(_res.options & RES_DEBUG, - (stdout, ";; timeout\n") - ); + (stdout, ";; timeout\n")); gotsomewhere = 1; _res_close(); goto next_ns; } + errno = 0; fromlen = sizeof(struct sockaddr_in); - resplen = recvfrom(s, ans, anssiz, 0, + resplen = recvfrom(s, (char*)ans, anssiz, 0, (struct sockaddr *)&from, &fromlen); if (resplen <= 0) { Perror(stderr, "recvfrom", errno); @@ -582,12 +588,12 @@ res_send(buf, buflen, ans, anssiz) DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_REPLY), (stdout, ";; old answer:\n"), - ans); + ans, resplen); goto wait; } #if CHECK_SRVR_ADDR if (!(_res.options & RES_INSECURE1) && - !our_server(&from)) { + !res_isourserver(&from)) { /* * response from wrong server? ignore it. * XXX - potential security hazard could @@ -596,12 +602,12 @@ res_send(buf, buflen, ans, anssiz) DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_REPLY), (stdout, ";; not our server:\n"), - ans); + ans, resplen); goto wait; } #endif if (!(_res.options & RES_INSECURE2) && - !queries_match(buf, buf + buflen, + !res_queriesmatch(buf, buf + buflen, ans, ans + anssiz)) { /* * response contains wrong query? ignore it. @@ -611,7 +617,7 @@ res_send(buf, buflen, ans, anssiz) DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_REPLY), (stdout, ";; wrong query name:\n"), - ans); + ans, resplen); goto wait; } if (anhp->rcode == SERVFAIL || @@ -619,9 +625,11 @@ res_send(buf, buflen, ans, anssiz) anhp->rcode == REFUSED) { DprintQ(_res.options & RES_DEBUG, (stdout, "server rejected query:\n"), - ans); + ans, resplen); badns |= (1<<ns); _res_close(); + /* don't retry if called from dig */ + if (!_res.pfcode) goto next_ns; } if (!(_res.options & RES_IGNTC) && anhp->tc) { @@ -630,8 +638,7 @@ res_send(buf, buflen, ans, anssiz) * use TCP with same server. */ Dprint(_res.options & RES_DEBUG, - (stdout, ";; truncated answer\n") - ); + (stdout, ";; truncated answer\n")); v_circuit = 1; _res_close(); goto same_ns; @@ -640,7 +647,7 @@ res_send(buf, buflen, ans, anssiz) DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_REPLY), (stdout, ";; got answer:\n"), - ans); + ans, resplen); /* * If using virtual circuits, we assume that the first server * is preferred over the rest (i.e. it is on the local @@ -659,12 +666,8 @@ res_send(buf, buflen, ans, anssiz) do { res_sendhookact act; - act = (*Rhook)(nsap, - buf, - buflen, - ans, - anssiz, - &resplen); + act = (*Rhook)(nsap, buf, buflen, + ans, anssiz, &resplen); switch (act) { case res_goahead: case res_done: @@ -691,14 +694,13 @@ res_send(buf, buflen, ans, anssiz) } /*foreach ns*/ } /*foreach retry*/ _res_close(); - if (!v_circuit) { + if (!v_circuit) if (!gotsomewhere) errno = ECONNREFUSED; /* no nameservers found */ else errno = ETIMEDOUT; /* no answer obtained */ - } else { + else errno = terrno; - } return (-1); } |