Commit | Line | Data |
---|---|---|
b423e985 | 1 | /* |
e9e1a1f3 | 2 | * Copyright (c) 1985, 1989 Regents of the University of California. |
6b2f9dd0 KB |
3 | * All rights reserved. |
4 | * | |
af359dea C |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * 2. Redistributions in binary form must reproduce the above copyright | |
11 | * notice, this list of conditions and the following disclaimer in the | |
12 | * documentation and/or other materials provided with the distribution. | |
13 | * 3. All advertising materials mentioning features or use of this software | |
14 | * must display the following acknowledgement: | |
15 | * This product includes software developed by the University of | |
16 | * California, Berkeley and its contributors. | |
17 | * 4. Neither the name of the University nor the names of its contributors | |
18 | * may be used to endorse or promote products derived from this software | |
19 | * without specific prior written permission. | |
20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
31 | * SUCH DAMAGE. | |
1c15e888 C |
32 | */ |
33 | ||
34 | #ifndef lint | |
af359dea | 35 | static char sccsid[] = "@(#)send.c 5.18 (Berkeley) 3/2/91"; |
1c15e888 C |
36 | #endif /* not lint */ |
37 | ||
38 | /* | |
39 | ******************************************************************************* | |
40 | * | |
41 | * send.c -- | |
42 | * | |
43 | * Routine to send request packets to a name server. | |
44 | * | |
45 | * Based on "@(#)res_send.c 6.25 (Berkeley) 6/1/90". | |
46 | * | |
47 | ******************************************************************************* | |
b423e985 RC |
48 | */ |
49 | ||
8ea4199d | 50 | |
616a94ba RC |
51 | /* |
52 | * Send query to name server and wait for reply. | |
53 | */ | |
54 | ||
04a773cb | 55 | #include <sys/param.h> |
616a94ba RC |
56 | #include <sys/time.h> |
57 | #include <sys/socket.h> | |
679f3274 | 58 | #include <sys/uio.h> |
616a94ba RC |
59 | #include <netinet/in.h> |
60 | #include <stdio.h> | |
61 | #include <errno.h> | |
27df2740 | 62 | #include <arpa/nameser.h> |
1c15e888 | 63 | #include <arpa/inet.h> |
f94b2f50 | 64 | #include <resolv.h> |
1c15e888 | 65 | #include "res.h" |
616a94ba RC |
66 | |
67 | extern int errno; | |
68 | ||
3126f4c0 | 69 | static int s = -1; /* socket used for communications */ |
1c15e888 | 70 | |
15537e14 KD |
71 | |
72 | #ifndef FD_SET | |
73 | #define NFDBITS 32 | |
74 | #define FD_SETSIZE 32 | |
75 | #define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) | |
76 | #define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) | |
77 | #define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) | |
78 | #define FD_ZERO(p) bzero((char *)(p), sizeof(*(p))) | |
79 | #endif | |
3126f4c0 | 80 | |
1c15e888 C |
81 | #define SR 1 /* SendRequest style */ |
82 | ||
83 | #ifndef DEBUG | |
84 | #define DEBUG | |
85 | #endif | |
86 | ||
87 | unsigned short nsport = NAMESERVER_PORT; | |
88 | ||
89 | ||
90 | \f | |
91 | /* | |
92 | ******************************************************************************* | |
93 | * | |
94 | * SendRequest -- | |
95 | * | |
96 | * Sends a request packet to a name server whose address | |
97 | * is specified by the first argument and returns with | |
98 | * the answer packet. | |
99 | * | |
100 | * Results: | |
101 | * SUCCESS - the request was sent and an answer | |
102 | * was received. | |
103 | * TIME_OUT - the virtual circuit connection timed-out | |
104 | * or a reply to a datagram wasn't received. | |
105 | * | |
106 | * | |
107 | ******************************************************************************* | |
108 | */ | |
109 | ||
110 | int | |
111 | SendRequest(nsAddrPtr, buf, buflen, answer, anslen, trueLenPtr) | |
112 | struct in_addr *nsAddrPtr; | |
113 | char *buf; | |
114 | int buflen; | |
115 | char *answer; | |
116 | u_int anslen; | |
117 | int *trueLenPtr; | |
616a94ba RC |
118 | { |
119 | register int n; | |
e9e1a1f3 | 120 | int try, v_circuit, resplen, ns; |
2344735f | 121 | int gotsomewhere = 0, connected = 0; |
17b5e053 | 122 | int connreset = 0; |
616a94ba RC |
123 | u_short id, len; |
124 | char *cp; | |
ac3ceb42 | 125 | fd_set dsmask; |
616a94ba RC |
126 | struct timeval timeout; |
127 | HEADER *hp = (HEADER *) buf; | |
128 | HEADER *anhp = (HEADER *) answer; | |
679f3274 | 129 | struct iovec iov[2]; |
1ea504e8 | 130 | int terrno = ETIMEDOUT; |
2344735f | 131 | char junk[512]; |
616a94ba | 132 | |
1c15e888 C |
133 | #if SR |
134 | struct sockaddr_in sin; | |
135 | ||
136 | if (_res.options & RES_DEBUG2) { | |
137 | printf("------------\nSendRequest(), len %d\n", buflen); | |
138 | Print_query(buf, buf+buflen, 1); | |
139 | } | |
140 | sin.sin_family = AF_INET; | |
141 | sin.sin_port = htons(nsport); | |
142 | sin.sin_addr = *nsAddrPtr; | |
143 | #else | |
ae94a224 | 144 | #ifdef DEBUG |
616a94ba | 145 | if (_res.options & RES_DEBUG) { |
31f0ead0 | 146 | printf("res_send()\n"); |
616a94ba RC |
147 | p_query(buf); |
148 | } | |
0b8992ca | 149 | #endif DEBUG |
31f0ead0 | 150 | if (!(_res.options & RES_INIT)) |
ae94a224 JB |
151 | if (res_init() == -1) { |
152 | return(-1); | |
153 | } | |
1c15e888 | 154 | #endif /* SR */ |
616a94ba RC |
155 | v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ; |
156 | id = hp->id; | |
157 | /* | |
158 | * Send request, RETRY times, or until successful | |
159 | */ | |
e9e1a1f3 | 160 | for (try = 0; try < _res.retry; try++) { |
1c15e888 | 161 | #if !SR |
0b8992ca KD |
162 | for (ns = 0; ns < _res.nscount; ns++) { |
163 | #ifdef DEBUG | |
164 | if (_res.options & RES_DEBUG) | |
165 | printf("Querying server (# %d) address = %s\n", ns+1, | |
2344735f | 166 | inet_ntoa(_res.nsaddr_list[ns].sin_addr)); |
0b8992ca | 167 | #endif DEBUG |
1c15e888 | 168 | #endif /* !SR */ |
e9e1a1f3 | 169 | usevc: |
616a94ba | 170 | if (v_circuit) { |
2344735f MK |
171 | int truncated = 0; |
172 | ||
616a94ba | 173 | /* |
e9e1a1f3 MK |
174 | * Use virtual circuit; |
175 | * at most one attempt per server. | |
616a94ba | 176 | */ |
e9e1a1f3 | 177 | try = _res.retry; |
a5d4a4c0 | 178 | if (s < 0) { |
616a94ba | 179 | s = socket(AF_INET, SOCK_STREAM, 0); |
92a82fe4 | 180 | if (s < 0) { |
1ea504e8 | 181 | terrno = errno; |
92a82fe4 MK |
182 | #ifdef DEBUG |
183 | if (_res.options & RES_DEBUG) | |
f7d00d5e | 184 | perror("socket (vc) failed"); |
92a82fe4 MK |
185 | #endif DEBUG |
186 | continue; | |
187 | } | |
1c15e888 | 188 | #if SR |
af359dea | 189 | if (connect(s, (struct sockaddr *)&sin, |
1c15e888 | 190 | #else |
af359dea C |
191 | if (connect(s, |
192 | (struct sockaddr *)&(_res.nsaddr_list[ns]), | |
1c15e888 | 193 | #endif |
a5d4a4c0 | 194 | sizeof(struct sockaddr)) < 0) { |
1ea504e8 | 195 | terrno = errno; |
ae94a224 | 196 | #ifdef DEBUG |
a5d4a4c0 | 197 | if (_res.options & RES_DEBUG) |
747d796e | 198 | perror("connect failed"); |
0b8992ca | 199 | #endif DEBUG |
a5d4a4c0 JB |
200 | (void) close(s); |
201 | s = -1; | |
202 | continue; | |
203 | } | |
616a94ba RC |
204 | } |
205 | /* | |
206 | * Send length & message | |
207 | */ | |
3126f4c0 | 208 | len = htons((u_short)buflen); |
679f3274 JB |
209 | iov[0].iov_base = (caddr_t)&len; |
210 | iov[0].iov_len = sizeof(len); | |
211 | iov[1].iov_base = buf; | |
212 | iov[1].iov_len = buflen; | |
213 | if (writev(s, iov, 2) != sizeof(len) + buflen) { | |
1ea504e8 | 214 | terrno = errno; |
ae94a224 | 215 | #ifdef DEBUG |
616a94ba | 216 | if (_res.options & RES_DEBUG) |
747d796e | 217 | perror("write failed"); |
0b8992ca | 218 | #endif DEBUG |
616a94ba RC |
219 | (void) close(s); |
220 | s = -1; | |
221 | continue; | |
222 | } | |
223 | /* | |
224 | * Receive length & response | |
225 | */ | |
226 | cp = answer; | |
227 | len = sizeof(short); | |
679f3274 | 228 | while (len != 0 && |
747d796e | 229 | (n = read(s, (char *)cp, (int)len)) > 0) { |
616a94ba RC |
230 | cp += n; |
231 | len -= n; | |
232 | } | |
233 | if (n <= 0) { | |
1ea504e8 | 234 | terrno = errno; |
ae94a224 | 235 | #ifdef DEBUG |
616a94ba | 236 | if (_res.options & RES_DEBUG) |
747d796e | 237 | perror("read failed"); |
0b8992ca | 238 | #endif DEBUG |
616a94ba RC |
239 | (void) close(s); |
240 | s = -1; | |
17b5e053 JB |
241 | /* |
242 | * A long running process might get its TCP | |
243 | * connection reset if the remote server was | |
244 | * restarted. Requery the server instead of | |
245 | * trying a new one. When there is only one | |
246 | * server, this means that a query might work | |
247 | * instead of failing. We only allow one reset | |
248 | * per query to prevent looping. | |
249 | */ | |
250 | if (terrno == ECONNRESET && !connreset) { | |
251 | connreset = 1; | |
252 | ns--; | |
253 | } | |
616a94ba RC |
254 | continue; |
255 | } | |
256 | cp = answer; | |
2344735f MK |
257 | if ((resplen = ntohs(*(u_short *)cp)) > anslen) { |
258 | #ifdef DEBUG | |
259 | if (_res.options & RES_DEBUG) | |
260 | fprintf(stderr, "response truncated\n"); | |
261 | #endif DEBUG | |
262 | len = anslen; | |
263 | truncated = 1; | |
264 | } else | |
265 | len = resplen; | |
679f3274 | 266 | while (len != 0 && |
747d796e | 267 | (n = read(s, (char *)cp, (int)len)) > 0) { |
616a94ba RC |
268 | cp += n; |
269 | len -= n; | |
270 | } | |
271 | if (n <= 0) { | |
1ea504e8 | 272 | terrno = errno; |
ae94a224 | 273 | #ifdef DEBUG |
616a94ba | 274 | if (_res.options & RES_DEBUG) |
747d796e | 275 | perror("read failed"); |
0b8992ca | 276 | #endif DEBUG |
616a94ba RC |
277 | (void) close(s); |
278 | s = -1; | |
279 | continue; | |
280 | } | |
2344735f MK |
281 | if (truncated) { |
282 | /* | |
283 | * Flush rest of answer | |
284 | * so connection stays in synch. | |
285 | */ | |
286 | anhp->tc = 1; | |
287 | len = resplen - anslen; | |
288 | while (len != 0) { | |
289 | n = (len > sizeof(junk) ? | |
290 | sizeof(junk) : len); | |
291 | if ((n = read(s, junk, n)) > 0) | |
292 | len -= n; | |
293 | else | |
294 | break; | |
295 | } | |
296 | } | |
616a94ba RC |
297 | } else { |
298 | /* | |
299 | * Use datagrams. | |
300 | */ | |
f7d00d5e | 301 | if (s < 0) { |
616a94ba | 302 | s = socket(AF_INET, SOCK_DGRAM, 0); |
f7d00d5e JB |
303 | if (s < 0) { |
304 | terrno = errno; | |
305 | #ifdef DEBUG | |
306 | if (_res.options & RES_DEBUG) | |
307 | perror("socket (dg) failed"); | |
308 | #endif DEBUG | |
309 | continue; | |
310 | } | |
311 | } | |
1c15e888 C |
312 | #if SR |
313 | /* | |
314 | * Special case the send code below | |
315 | * since we have just 1 server. | |
316 | */ | |
317 | #if BSD >= 43 | |
318 | if (connected == 0) { | |
af359dea | 319 | if (connect(s, (struct sockaddr *)&sin, |
1c15e888 C |
320 | sizeof(struct sockaddr)) < 0) { |
321 | if (_res.options & RES_DEBUG) | |
322 | perror("connect"); | |
323 | continue; | |
324 | } | |
325 | connected = 1; | |
326 | } | |
327 | if (send(s, buf, buflen, 0) != buflen) { | |
328 | if (_res.options & RES_DEBUG) | |
329 | perror("send"); | |
330 | continue; | |
331 | } | |
332 | #else /* BSD */ | |
333 | if (sendto(s, buf, buflen, 0, &sin, | |
334 | sizeof(struct sockaddr)) != buflen) { | |
335 | if (_res.options & RES_DEBUG) | |
336 | perror("sendto"); | |
337 | continue; | |
338 | } | |
339 | #endif | |
340 | #else /* SR */ | |
92a82fe4 | 341 | #if BSD >= 43 |
e9e1a1f3 MK |
342 | /* |
343 | * I'm tired of answering this question, so: | |
344 | * On a 4.3BSD+ machine (client and server, | |
345 | * actually), sending to a nameserver datagram | |
346 | * port with no nameserver will cause an | |
347 | * ICMP port unreachable message to be returned. | |
348 | * If our datagram socket is "connected" to the | |
349 | * server, we get an ECONNREFUSED error on the next | |
350 | * socket operation, and select returns if the | |
351 | * error message is received. We can thus detect | |
352 | * the absence of a nameserver without timing out. | |
353 | * If we have sent queries to at least two servers, | |
354 | * however, we don't want to remain connected, | |
355 | * as we wish to receive answers from the first | |
356 | * server to respond. | |
357 | */ | |
358 | if (_res.nscount == 1 || (try == 0 && ns == 0)) { | |
7a8f7802 | 359 | /* |
9bb3997d MK |
360 | * Don't use connect if we might |
361 | * still receive a response | |
362 | * from another server. | |
7a8f7802 | 363 | */ |
2344735f MK |
364 | if (connected == 0) { |
365 | if (connect(s, &_res.nsaddr_list[ns], | |
366 | sizeof(struct sockaddr)) < 0) { | |
367 | #ifdef DEBUG | |
368 | if (_res.options & RES_DEBUG) | |
369 | perror("connect"); | |
370 | #endif DEBUG | |
371 | continue; | |
372 | } | |
373 | connected = 1; | |
374 | } | |
375 | if (send(s, buf, buflen, 0) != buflen) { | |
ae94a224 | 376 | #ifdef DEBUG |
7a8f7802 | 377 | if (_res.options & RES_DEBUG) |
2344735f | 378 | perror("send"); |
0b8992ca | 379 | #endif DEBUG |
7a8f7802 KD |
380 | continue; |
381 | } | |
fee59cfd MK |
382 | } else { |
383 | /* | |
384 | * Disconnect if we want to listen | |
385 | * for responses from more than one server. | |
386 | */ | |
387 | if (connected) { | |
388 | (void) connect(s, &no_addr, | |
389 | sizeof(no_addr)); | |
390 | connected = 0; | |
391 | } | |
7a8f7802 | 392 | #endif BSD |
fee59cfd MK |
393 | if (sendto(s, buf, buflen, 0, |
394 | &_res.nsaddr_list[ns], | |
395 | sizeof(struct sockaddr)) != buflen) { | |
92a82fe4 | 396 | #ifdef DEBUG |
fee59cfd MK |
397 | if (_res.options & RES_DEBUG) |
398 | perror("sendto"); | |
92a82fe4 | 399 | #endif DEBUG |
fee59cfd MK |
400 | continue; |
401 | } | |
402 | #if BSD >= 43 | |
616a94ba | 403 | } |
fee59cfd | 404 | #endif |
1c15e888 | 405 | #endif /* SR */ |
7a8f7802 | 406 | |
616a94ba | 407 | /* |
747d796e | 408 | * Wait for reply |
616a94ba | 409 | */ |
e9e1a1f3 | 410 | timeout.tv_sec = (_res.retrans << try); |
1c15e888 | 411 | #if !SR |
e9e1a1f3 MK |
412 | if (try > 0) |
413 | timeout.tv_sec /= _res.nscount; | |
1c15e888 | 414 | #endif /* SR */ |
747d796e KD |
415 | if (timeout.tv_sec <= 0) |
416 | timeout.tv_sec = 1; | |
616a94ba | 417 | timeout.tv_usec = 0; |
87b12937 | 418 | wait: |
ac3ceb42 KD |
419 | FD_ZERO(&dsmask); |
420 | FD_SET(s, &dsmask); | |
679f3274 JB |
421 | n = select(s+1, &dsmask, (fd_set *)NULL, |
422 | (fd_set *)NULL, &timeout); | |
616a94ba | 423 | if (n < 0) { |
ae94a224 | 424 | #ifdef DEBUG |
616a94ba | 425 | if (_res.options & RES_DEBUG) |
747d796e | 426 | perror("select"); |
0b8992ca | 427 | #endif DEBUG |
616a94ba RC |
428 | continue; |
429 | } | |
430 | if (n == 0) { | |
431 | /* | |
432 | * timeout | |
433 | */ | |
ae94a224 | 434 | #ifdef DEBUG |
616a94ba | 435 | if (_res.options & RES_DEBUG) |
1c15e888 C |
436 | printf("timeout (%d secs)\n", |
437 | timeout.tv_sec); | |
0b8992ca | 438 | #endif DEBUG |
e9e1a1f3 | 439 | #if BSD >= 43 |
92a82fe4 | 440 | gotsomewhere = 1; |
e9e1a1f3 | 441 | #endif |
616a94ba RC |
442 | continue; |
443 | } | |
dd7a6a73 | 444 | if ((resplen = recv(s, answer, anslen, 0)) <= 0) { |
ae94a224 | 445 | #ifdef DEBUG |
616a94ba | 446 | if (_res.options & RES_DEBUG) |
747d796e | 447 | perror("recvfrom"); |
0b8992ca | 448 | #endif DEBUG |
616a94ba RC |
449 | continue; |
450 | } | |
92a82fe4 | 451 | gotsomewhere = 1; |
616a94ba RC |
452 | if (id != anhp->id) { |
453 | /* | |
454 | * response from old query, ignore it | |
455 | */ | |
1c15e888 C |
456 | #if SR |
457 | if (_res.options & RES_DEBUG2) { | |
458 | printf("------------\nOld answer:\n"); | |
459 | Print_query(answer, answer+resplen, 1); | |
460 | } | |
461 | #else | |
ae94a224 | 462 | #ifdef DEBUG |
616a94ba | 463 | if (_res.options & RES_DEBUG) { |
616a94ba | 464 | printf("old answer:\n"); |
616a94ba RC |
465 | p_query(answer); |
466 | } | |
0b8992ca | 467 | #endif DEBUG |
1c15e888 | 468 | #endif |
87b12937 | 469 | goto wait; |
616a94ba RC |
470 | } |
471 | if (!(_res.options & RES_IGNTC) && anhp->tc) { | |
472 | /* | |
e9e1a1f3 MK |
473 | * get rest of answer; |
474 | * use TCP with same server. | |
616a94ba | 475 | */ |
ae94a224 | 476 | #ifdef DEBUG |
616a94ba RC |
477 | if (_res.options & RES_DEBUG) |
478 | printf("truncated answer\n"); | |
0b8992ca | 479 | #endif DEBUG |
616a94ba RC |
480 | (void) close(s); |
481 | s = -1; | |
616a94ba | 482 | v_circuit = 1; |
e9e1a1f3 | 483 | goto usevc; |
616a94ba RC |
484 | } |
485 | } | |
1c15e888 C |
486 | #if SR |
487 | if (_res.options & RES_DEBUG) { | |
488 | if (_res.options & RES_DEBUG2) | |
489 | printf("------------\nGot answer (%d bytes):\n", | |
490 | resplen); | |
491 | else | |
492 | printf("------------\nGot answer:\n"); | |
493 | Print_query(answer, answer+resplen, 1); | |
494 | } | |
495 | (void) close(s); | |
496 | s = -1; | |
497 | *trueLenPtr = resplen; | |
498 | return (SUCCESS); | |
499 | #else | |
ae94a224 | 500 | #ifdef DEBUG |
616a94ba RC |
501 | if (_res.options & RES_DEBUG) { |
502 | printf("got answer:\n"); | |
503 | p_query(answer); | |
504 | } | |
0b8992ca | 505 | #endif DEBUG |
a5d4a4c0 | 506 | /* |
e9e1a1f3 MK |
507 | * If using virtual circuits, we assume that the first server |
508 | * is preferred * over the rest (i.e. it is on the local | |
509 | * machine) and only keep that one open. | |
510 | * If we have temporarily opened a virtual circuit, | |
511 | * or if we haven't been asked to keep a socket open, | |
512 | * close the socket. | |
a5d4a4c0 | 513 | */ |
e9e1a1f3 MK |
514 | if ((v_circuit && |
515 | ((_res.options & RES_USEVC) == 0 || ns != 0)) || | |
516 | (_res.options & RES_STAYOPEN) == 0) { | |
a5d4a4c0 JB |
517 | (void) close(s); |
518 | s = -1; | |
a5d4a4c0 | 519 | } |
fee59cfd | 520 | return (resplen); |
0b8992ca | 521 | } |
1c15e888 | 522 | #endif /* SR */ |
616a94ba | 523 | } |
1ea504e8 JB |
524 | if (s >= 0) { |
525 | (void) close(s); | |
526 | s = -1; | |
527 | } | |
1c15e888 C |
528 | #if SR |
529 | if (v_circuit == 0) | |
530 | if (gotsomewhere == 0) | |
531 | return NO_RESPONSE; /* no nameservers found */ | |
532 | else | |
533 | return TIME_OUT; /* no answer obtained */ | |
534 | else | |
535 | if (errno == ECONNREFUSED) | |
536 | return NO_RESPONSE; | |
537 | else | |
538 | return ERROR; | |
539 | #else | |
1ea504e8 JB |
540 | if (v_circuit == 0) |
541 | if (gotsomewhere == 0) | |
e9e1a1f3 | 542 | errno = ECONNREFUSED; /* no nameservers found */ |
1ea504e8 | 543 | else |
e9e1a1f3 | 544 | errno = ETIMEDOUT; /* no answer obtained */ |
92a82fe4 | 545 | else |
1ea504e8 | 546 | errno = terrno; |
616a94ba | 547 | return (-1); |
1c15e888 | 548 | #endif |
616a94ba | 549 | } |
3126f4c0 JB |
550 | |
551 | /* | |
552 | * This routine is for closing the socket if a virtual circuit is used and | |
1c15e888 | 553 | * the program wants to close it. |
3126f4c0 | 554 | * |
1c15e888 | 555 | * Called from the interrupt handler. |
3126f4c0 | 556 | */ |
1c15e888 | 557 | SendRequest_close() |
3126f4c0 JB |
558 | { |
559 | if (s != -1) { | |
560 | (void) close(s); | |
561 | s = -1; | |
562 | } | |
563 | } |