X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/9bb3997d0c80bd04d0fcb11d9bebdafd9dd20344..fad613b52dda8749b9b9e5493557045b54baf496:/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 afb74ddd44..36b23fe055 100644 --- a/usr/src/lib/libc/net/res_send.c +++ b/usr/src/lib/libc/net/res_send.c @@ -1,13 +1,18 @@ - /* * Copyright (c) 1985 Regents of the University of California. - * All rights reserved. The Berkeley software License Agreement - * specifies the terms and conditions for redistribution. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of California at Berkeley. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. This software + * is provided ``as is'' without express or implied warranty. */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)res_send.c 6.17 (Berkeley) %G%"; -#endif LIBC_SCCS and not lint +static char sccsid[] = "@(#)res_send.c 6.19 (Berkeley) %G%"; +#endif /* LIBC_SCCS and not lint */ /* * Send query to name server and wait for reply. @@ -48,7 +53,7 @@ res_send(buf, buflen, answer, anslen) { register int n; int retry, v_circuit, resplen, ns; - int gotsomewhere = 0; + int gotsomewhere = 0, connected = 0; u_short id, len; char *cp; fd_set dsmask; @@ -57,6 +62,7 @@ res_send(buf, buflen, answer, anslen) HEADER *anhp = (HEADER *) answer; struct iovec iov[2]; int terrno = ETIMEDOUT; + char junk[512]; #ifdef DEBUG if (_res.options & RES_DEBUG) { @@ -78,9 +84,11 @@ res_send(buf, buflen, answer, anslen) #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)); + inet_ntoa(_res.nsaddr_list[ns].sin_addr)); #endif DEBUG if (v_circuit) { + int truncated = 0; + /* * Use virtual circuit. */ @@ -145,7 +153,15 @@ res_send(buf, buflen, answer, anslen) continue; } cp = answer; - resplen = len = ntohs(*(u_short *)cp); + if ((resplen = ntohs(*(u_short *)cp)) > anslen) { +#ifdef DEBUG + if (_res.options & RES_DEBUG) + fprintf(stderr, "response truncated\n"); +#endif DEBUG + len = anslen; + truncated = 1; + } else + len = resplen; while (len != 0 && (n = read(s, (char *)cp, (int)len)) > 0) { cp += n; @@ -161,6 +177,22 @@ res_send(buf, buflen, answer, anslen) s = -1; continue; } + if (truncated) { + /* + * Flush rest of answer + * so connection stays in synch. + */ + anhp->tc = 1; + len = resplen - anslen; + while (len != 0) { + n = (len > sizeof(junk) ? + sizeof(junk) : len); + if ((n = read(s, junk, n)) > 0) + len -= n; + else + break; + } + } } else { /* * Use datagrams. @@ -174,12 +206,21 @@ res_send(buf, buflen, answer, anslen) * still receive a response * from another server. */ - if (connect(s, &_res.nsaddr_list[ns], - sizeof(struct sockaddr)) < 0 || - send(s, buf, buflen, 0) != buflen) { + if (connected == 0) { + if (connect(s, &_res.nsaddr_list[ns], + sizeof(struct sockaddr)) < 0) { +#ifdef DEBUG + if (_res.options & RES_DEBUG) + perror("connect"); +#endif DEBUG + continue; + } + connected = 1; + } + if (send(s, buf, buflen, 0) != buflen) { #ifdef DEBUG if (_res.options & RES_DEBUG) - perror("connect"); + perror("send"); #endif DEBUG continue; } @@ -226,9 +267,11 @@ wait: * Disconnect if we want to listen * for responses from more than one server. */ - if (_res.nscount > 1 && retry == _res.retry) + if (_res.nscount > 1 && connected) { (void) connect(s, &no_addr, sizeof(no_addr)); + connected = 0; + } gotsomewhere = 1; continue; }