summaryrefslogtreecommitdiffstats
path: root/lib/libc/net/res_send.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/net/res_send.c')
-rw-r--r--lib/libc/net/res_send.c142
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);
}
OpenPOWER on IntegriCloud