Move /usr/include/nameser.h & reslov.h to /usr/include/arpa
[unix-history] / usr / src / lib / libc / net / res_send.c
CommitLineData
b423e985 1/*
8ea4199d
DF
2 * Copyright (c) 1985 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
b423e985
RC
5 */
6
8ea4199d 7#ifndef lint
27df2740 8static char sccsid[] = "@(#)res_send.c 5.4 (Berkeley) %G%";
8ea4199d
DF
9#endif not lint
10
616a94ba
RC
11/*
12 * Send query to name server and wait for reply.
13 */
14
15#include <sys/types.h>
16#include <sys/time.h>
17#include <sys/socket.h>
18#include <netinet/in.h>
19#include <stdio.h>
20#include <errno.h>
27df2740
KD
21#include <arpa/nameser.h>
22#include <arpa/resolv.h>
616a94ba
RC
23
24extern int errno;
25
31f0ead0 26res_send(buf, buflen, answer, anslen)
616a94ba
RC
27 char *buf;
28 int buflen;
29 char *answer;
30 int anslen;
31{
32 register int n;
33 int s, retry, v_circuit, resplen;
34 u_short id, len;
35 char *cp;
36 int dsmask;
37 struct timeval timeout;
38 HEADER *hp = (HEADER *) buf;
39 HEADER *anhp = (HEADER *) answer;
40
41 if (_res.options & RES_DEBUG) {
31f0ead0 42 printf("res_send()\n");
616a94ba
RC
43 p_query(buf);
44 }
31f0ead0
RC
45 if (!(_res.options & RES_INIT))
46 res_init();
616a94ba
RC
47 s = -1;
48 v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
49 id = hp->id;
50 /*
51 * Send request, RETRY times, or until successful
52 */
53 for (retry = _res.retry; --retry >= 0; ) {
54 if (v_circuit) {
55 /*
56 * Use virtual circuit.
57 */
58 if (s < 0)
59 s = socket(AF_INET, SOCK_STREAM, 0);
60 if (connect(s, &_res.nsaddr, sizeof(_res.nsaddr)) < 0) {
61 if (_res.options & RES_DEBUG)
62 printf("connect failed %d\n", errno);
63 (void) close(s);
64 s = -1;
65 continue;
66 }
67 /*
68 * Send length & message
69 */
70 len = htons(buflen);
71 if (write(s, &len, sizeof(len)) != sizeof(len) ||
72 write(s, buf, buflen) != buflen) {
73 if (_res.options & RES_DEBUG)
74 printf("write failed %d\n", errno);
75 (void) close(s);
76 s = -1;
77 continue;
78 }
79 /*
80 * Receive length & response
81 */
82 cp = answer;
83 len = sizeof(short);
84 while (len > 0 && (n = read(s, cp, len)) > 0) {
85 cp += n;
86 len -= n;
87 }
88 if (n <= 0) {
89 if (_res.options & RES_DEBUG)
90 printf("read failed %d\n", errno);
91 (void) close(s);
92 s = -1;
93 continue;
94 }
95 cp = answer;
96 resplen = len = ntohs(*(short *)cp);
97 while (len > 0 && (n = read(s, cp, len)) > 0) {
98 cp += n;
99 len -= n;
100 }
101 if (n <= 0) {
102 if (_res.options & RES_DEBUG)
103 printf("read failed %d\n", errno);
104 (void) close(s);
105 s = -1;
106 continue;
107 }
108 } else {
109 /*
110 * Use datagrams.
111 */
112 if (s < 0)
113 s = socket(AF_INET, SOCK_DGRAM, 0);
114 if (sendto(s, buf, buflen, 0, &_res.nsaddr,
115 sizeof(_res.nsaddr)) != buflen) {
116 if (_res.options & RES_DEBUG)
117 printf("sendto errno = %d\n", errno);
118 }
119 /*
120 * Wait for reply
121 */
122 timeout.tv_sec = _res.retrans;
123 timeout.tv_usec = 0;
124 dsmask = 1 << s;
125 n = select(s+1, &dsmask, 0, 0, &timeout);
126 if (n < 0) {
127 if (_res.options & RES_DEBUG)
128 printf("select errno = %d\n", errno);
129 continue;
130 }
131 if (n == 0) {
132 /*
133 * timeout
134 */
135 if (_res.options & RES_DEBUG)
136 printf("timeout\n");
137 continue;
138 }
139 if ((resplen = recvfrom(s, answer, anslen,
140 0, 0, 0)) <= 0) {
141 if (_res.options & RES_DEBUG)
142 printf("recvfrom, errno=%d\n", errno);
143 continue;
144 }
145 if (id != anhp->id) {
146 /*
147 * response from old query, ignore it
148 */
149 if (_res.options & RES_DEBUG) {
616a94ba 150 printf("old answer:\n");
616a94ba
RC
151 p_query(answer);
152 }
153 continue;
154 }
155 if (!(_res.options & RES_IGNTC) && anhp->tc) {
156 /*
157 * get rest of answer
158 */
159 if (_res.options & RES_DEBUG)
160 printf("truncated answer\n");
161 (void) close(s);
162 s = -1;
163 retry = _res.retry;
164 v_circuit = 1;
165 continue;
166 }
167 }
168 if (_res.options & RES_DEBUG) {
169 printf("got answer:\n");
170 p_query(answer);
171 }
e96fe2f7 172 (void) close(s);
616a94ba
RC
173 return (resplen);
174 }
e96fe2f7 175 (void) close(s);
31b63904 176 errno = ETIMEDOUT;
616a94ba
RC
177 return (-1);
178}