projects
/
unix-history
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
tags
|
clone url
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
use connect on dg sockets to allow unreachable reporting;
[unix-history]
/
usr
/
src
/
lib
/
libc
/
net
/
res_send.c
diff --git
a/usr/src/lib/libc/net/res_send.c
b/usr/src/lib/libc/net/res_send.c
index
dfd75e7
..
9e37090
100644
(file)
--- a/
usr/src/lib/libc/net/res_send.c
+++ b/
usr/src/lib/libc/net/res_send.c
@@
-1,3
+1,4
@@
+
/*
* Copyright (c) 1985 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
/*
* Copyright (c) 1985 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
@@
-5,7
+6,7
@@
*/
#ifndef lint
*/
#ifndef lint
-static char sccsid[] = "@(#)res_send.c
5.5
(Berkeley) %G%";
+static char sccsid[] = "@(#)res_send.c
6.3
(Berkeley) %G%";
#endif not lint
/*
#endif not lint
/*
@@
-23,6
+24,8
@@
static char sccsid[] = "@(#)res_send.c 5.5 (Berkeley) %G%";
extern int errno;
extern int errno;
+#define KEEPOPEN (RES_USEVC|RES_STAYOPEN)
+
res_send(buf, buflen, answer, anslen)
char *buf;
int buflen;
res_send(buf, buflen, answer, anslen)
char *buf;
int buflen;
@@
-30,7
+33,8
@@
res_send(buf, buflen, answer, anslen)
int anslen;
{
register int n;
int anslen;
{
register int n;
- int s, retry, v_circuit, resplen;
+ int retry, v_circuit, resplen, ns;
+ static int s = -1;
u_short id, len;
char *cp;
int dsmask;
u_short id, len;
char *cp;
int dsmask;
@@
-43,43
+47,50
@@
res_send(buf, buflen, answer, anslen)
printf("res_send()\n");
p_query(buf);
}
printf("res_send()\n");
p_query(buf);
}
-#endif
+#endif
DEBUG
if (!(_res.options & RES_INIT))
if (res_init() == -1) {
return(-1);
}
if (!(_res.options & RES_INIT))
if (res_init() == -1) {
return(-1);
}
- s = -1;
v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
id = hp->id;
/*
* Send request, RETRY times, or until successful
*/
for (retry = _res.retry; --retry >= 0; ) {
v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
id = hp->id;
/*
* Send request, RETRY times, or until successful
*/
for (retry = _res.retry; --retry >= 0; ) {
+ for (ns = 0; ns < _res.nscount; ns++) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf("Querying server (# %d) address = %s\n", ns+1,
+ inet_ntoa(_res.nsaddr_list[ns].sin_addr.s_addr));
+#endif DEBUG
if (v_circuit) {
/*
* Use virtual circuit.
*/
if (v_circuit) {
/*
* Use virtual circuit.
*/
- if (s < 0)
+ if (s < 0)
{
s = socket(AF_INET, SOCK_STREAM, 0);
s = socket(AF_INET, SOCK_STREAM, 0);
- if (connect(s, &_res.nsaddr, sizeof(_res.nsaddr)) < 0) {
+ if (connect(s, &(_res.nsaddr_list[ns]),
+ sizeof(struct sockaddr)) < 0) {
#ifdef DEBUG
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
- printf("connect failed %d\n", errno);
-#endif
- (void) close(s);
- s = -1;
- continue;
+ if (_res.options & RES_DEBUG)
+ printf("connect failed %d\n",errno);
+#endif DEBUG
+ (void) close(s);
+ s = -1;
+ continue;
+ }
}
/*
* Send length & message
*/
len = htons(buflen);
if (write(s, &len, sizeof(len)) != sizeof(len) ||
}
/*
* Send length & message
*/
len = htons(buflen);
if (write(s, &len, sizeof(len)) != sizeof(len) ||
- write(s, buf, buflen) != buflen) {
+
write(s, buf, buflen) != buflen) {
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf("write failed %d\n", errno);
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf("write failed %d\n", errno);
-#endif
+#endif
DEBUG
(void) close(s);
s = -1;
continue;
(void) close(s);
s = -1;
continue;
@@
-97,7
+108,7
@@
res_send(buf, buflen, answer, anslen)
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf("read failed %d\n", errno);
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf("read failed %d\n", errno);
-#endif
+#endif
DEBUG
(void) close(s);
s = -1;
continue;
(void) close(s);
s = -1;
continue;
@@
-112,7
+123,7
@@
res_send(buf, buflen, answer, anslen)
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf("read failed %d\n", errno);
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf("read failed %d\n", errno);
-#endif
+#endif
DEBUG
(void) close(s);
s = -1;
continue;
(void) close(s);
s = -1;
continue;
@@
-123,25
+134,29
@@
res_send(buf, buflen, answer, anslen)
*/
if (s < 0)
s = socket(AF_INET, SOCK_DGRAM, 0);
*/
if (s < 0)
s = socket(AF_INET, SOCK_DGRAM, 0);
- if (sendto(s, buf, buflen, 0, &_res.nsaddr,
- sizeof(_res.nsaddr)) != buflen) {
+ if (connect(s, &_res.nsaddr_list[ns],
+ sizeof(struct sockaddr)) < 0 ||
+ send(s, buf, buflen, 0) != buflen) {
#ifdef DEBUG
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
- printf("sendto errno = %d\n", errno);
-#endif
+ if (_res.options & RES_DEBUG)
+ printf("connect/send errno = %d\n",
+ errno);
+#endif DEBUG
}
/*
* Wait for reply
*/
}
/*
* Wait for reply
*/
- timeout.tv_sec = _res.retrans;
+ timeout.tv_sec =
+ ((_res.retrans * _res.retry) / _res.nscount);
timeout.tv_usec = 0;
timeout.tv_usec = 0;
+wait:
dsmask = 1 << s;
n = select(s+1, &dsmask, 0, 0, &timeout);
if (n < 0) {
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf("select errno = %d\n", errno);
dsmask = 1 << s;
n = select(s+1, &dsmask, 0, 0, &timeout);
if (n < 0) {
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf("select errno = %d\n", errno);
-#endif
+#endif
DEBUG
continue;
}
if (n == 0) {
continue;
}
if (n == 0) {
@@
-151,15
+166,14
@@
res_send(buf, buflen, answer, anslen)
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf("timeout\n");
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf("timeout\n");
-#endif
+#endif
DEBUG
continue;
}
continue;
}
- if ((resplen = recvfrom(s, answer, anslen,
- 0, 0, 0)) <= 0) {
+ if ((resplen = recv(s, answer, anslen, 0)) <= 0) {
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf("recvfrom, errno=%d\n", errno);
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf("recvfrom, errno=%d\n", errno);
-#endif
+#endif
DEBUG
continue;
}
if (id != anhp->id) {
continue;
}
if (id != anhp->id) {
@@
-171,8
+185,8
@@
res_send(buf, buflen, answer, anslen)
printf("old answer:\n");
p_query(answer);
}
printf("old answer:\n");
p_query(answer);
}
-#endif
-
continue
;
+#endif
DEBUG
+
goto wait
;
}
if (!(_res.options & RES_IGNTC) && anhp->tc) {
/*
}
if (!(_res.options & RES_IGNTC) && anhp->tc) {
/*
@@
-181,7
+195,7
@@
res_send(buf, buflen, answer, anslen)
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf("truncated answer\n");
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf("truncated answer\n");
-#endif
+#endif
DEBUG
(void) close(s);
s = -1;
retry = _res.retry;
(void) close(s);
s = -1;
retry = _res.retry;
@@
-194,9
+208,20
@@
res_send(buf, buflen, answer, anslen)
printf("got answer:\n");
p_query(answer);
}
printf("got answer:\n");
p_query(answer);
}
-#endif
- (void) close(s);
- return (resplen);
+#endif DEBUG
+ /*
+ * We are going to assume that the first server is preferred
+ * over the rest (i.e. it is on the local machine) and only
+ * keep that one open.
+ */
+ if ((_res.options & KEEPOPEN) == KEEPOPEN && ns == 0) {
+ return (resplen);
+ } else {
+ (void) close(s);
+ s = -1;
+ return (resplen);
+ }
+ }
}
(void) close(s);
errno = ETIMEDOUT;
}
(void) close(s);
errno = ETIMEDOUT;