1: /*
   2:  *******************************************************************************
   3:  *
   4:  *  send.c --
   5:  *
   6:  *	Routine to send request packets to a name server.
   7:  *
   8:  *	Modified version of 4.3BSD BIND  res_send.c 5.5 (Berkeley) 9/14/85
   9:  *
  10:  *	Copyright (c) 1985 Regents of the University of California.
  11:  *	All rights reserved.  The Berkeley software License Agreement
  12:  *	specifies the terms and conditions for redistribution.
  13:  *
  14:  *******************************************************************************
  15:  */
  16: 
  17: #ifndef lint
  18: static char sccsid[] = "@(#)send.c	5.3 (Berkeley) 3/31/86";
  19: #endif not lint
  20: 
  21: #include <sys/types.h>
  22: #include <sys/time.h>
  23: #include <sys/socket.h>
  24: #include <netinet/in.h>
  25: #include <stdio.h>
  26: #include <arpa/nameser.h>
  27: #include <resolv.h>
  28: #include "res.h"
  29: 
  30: /*
  31:  *  Initialize the socket address info struct.
  32:  */
  33: 
  34: static struct sockaddr_in sin = {
  35:     AF_INET,
  36: };
  37: 
  38: 
  39: /*
  40:  *******************************************************************************
  41:  *
  42:  *   SendRequest --
  43:  *
  44:  *	Sends a request packet to a name server whose address
  45:  *	is specified by the first argument and returns with
  46:  *	the answer packet.
  47:  *
  48:  *  Results:
  49:  *	SUCCESS		- the request was sent and an answer
  50:  *			  was received.
  51:  *	TIME_OUT	- the virtual circuit connection timed-out
  52:  *			  or a reply to a datagram wasn't received.
  53:  *
  54:  *
  55:  *******************************************************************************
  56:  */
  57: 
  58: int
  59: SendRequest(nsAddrPtr, buf, buflen, answer, anslen, trueLenPtr)
  60:     struct in_addr  *nsAddrPtr;
  61:     char        *buf;
  62:     int         buflen;
  63:     char        *answer;
  64:     int         anslen;
  65:     int         *trueLenPtr;
  66: {
  67:     struct timeval  timeout;
  68:     register int    n;
  69:     u_short     packetId, len;
  70:     short       length;
  71:     char        *cp;
  72:     int         retry, v_circuit, resplen;
  73:     int         dsmask;
  74: 
  75:     int         numTimeOuts = 0;
  76:     HEADER      *requestPtr = (HEADER *) buf;
  77:     HEADER      *answerPtr  = (HEADER *) answer;
  78: 
  79: 
  80:     if (_res.options & RES_DEBUG2) {
  81:         printf("SendRequest()\n");
  82:         Print_query(buf, buf+buflen, 1);
  83:     }
  84:     sockFD = -1;
  85: 
  86:     /*
  87: 	 * See if a virtual circuit is required or desired.
  88: 	 */
  89:     v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
  90: 
  91:     packetId = requestPtr->id;
  92: 
  93:     sin.sin_port    = htons(NAMESERVER_PORT);
  94:     sin.sin_addr    = *nsAddrPtr;
  95: 
  96:     /*
  97: 	 * Send request, RETRY times, or until successful
  98: 	 */
  99:     for (retry = _res.retry; --retry >= 0; ) {
 100:         if (v_circuit) {
 101:             /*
 102: 			 * Use virtual circuit.
 103: 			 */
 104:             if (sockFD < 0)
 105:                 sockFD = socket(AF_INET, SOCK_STREAM, 0);
 106: 
 107:             if (connect(sockFD, &sin, sizeof(sin)) < 0) {
 108:                 if (_res.options & RES_DEBUG) {
 109:                     perror("SendRequest");
 110:                 }
 111:                 (void) close(sockFD);
 112:                 sockFD = -1;
 113:                 continue;
 114:             }
 115:             /*
 116: 			 * Send length & message
 117: 			 */
 118:             len = htons(buflen);
 119:             if (write(sockFD, &len, sizeof(len)) != sizeof(len) ||
 120:                 write(sockFD, buf, buflen) != buflen) {
 121:                 if (_res.options & RES_DEBUG) {
 122:                     perror("SendRequest");
 123:                 }
 124:                 (void) close(sockFD);
 125:                 sockFD = -1;
 126:                 continue;
 127:             }
 128:             /*
 129: 			 * Receive length & response
 130: 			 */
 131:             cp = answer;
 132:             length = sizeof(short);
 133:             while(length > 0 && (n = read(sockFD, cp, length)) > 0){
 134:                 cp += n;
 135:                 length -= n;
 136:             }
 137:             if (n <= 0) {
 138:                 if (_res.options & RES_DEBUG) {
 139:                     perror("SendRequest");
 140:                 }
 141:                 (void) close(sockFD);
 142:                 sockFD = -1;
 143:                 continue;
 144:             }
 145:             cp = answer;
 146:             resplen = length = ntohs(*(short *)cp);
 147:             while(length > 0 && (n = read(sockFD, cp, length)) > 0){
 148:                 cp += n;
 149:                 length -= n;
 150:             }
 151:             if (n <= 0) {
 152:                 if (_res.options & RES_DEBUG) {
 153:                     perror("SendRequest");
 154:                 }
 155:                 (void) close(sockFD);
 156:                 sockFD = -1;
 157:                 continue;
 158:             }
 159:         } else {
 160:             /*
 161: 			 * Use datagrams.
 162: 			 */
 163:             if (sockFD < 0)
 164:                 sockFD = socket(AF_INET, SOCK_DGRAM, 0);
 165: 
 166:             if (sendto(sockFD, buf, buflen, 0, &sin,
 167:                 sizeof(sin)) != buflen) {
 168:                 if (_res.options & RES_DEBUG) {
 169:                     perror("SendRequest");
 170:                 }
 171:             }
 172:             /*
 173: 			 * Wait for reply
 174: 			 */
 175:             timeout.tv_sec = _res.retrans;
 176:             timeout.tv_usec = 0;
 177:             dsmask = 1 << sockFD;
 178:             n = select(sockFD+1, &dsmask, 0, 0, &timeout);
 179:             if (n < 0) {
 180:                 if (_res.options & RES_DEBUG) {
 181:                     perror("SendRequest");
 182:                 }
 183:                 continue;
 184:             }
 185:             if (n == 0) {
 186:                 /*
 187: 				 * timeout
 188: 				 */
 189:                 if (_res.options & RES_DEBUG) {
 190:                     printf("Timeout %d\n", ++numTimeOuts);
 191:                 }
 192:                 continue;
 193:             }
 194:             if ((resplen = recv(sockFD, answer, anslen, 0)) <= 0) {
 195:                 if (_res.options & RES_DEBUG) {
 196:                     perror("SendRequest");
 197:                 }
 198:                 continue;
 199:             }
 200:             if (packetId != answerPtr->id) {
 201:                 /*
 202: 				 * response from old query, ignore it
 203: 				 */
 204:                 if (_res.options & RES_DEBUG2) {
 205:                     printf("Old answer:\n");
 206:                     Print_query(answer, answer+resplen, 1);
 207:                 }
 208:                 continue;
 209:             }
 210:             if (!(_res.options & RES_IGNTC) && answerPtr->tc) {
 211:                 /*
 212: 				 * get rest of answer
 213: 				 */
 214:                 if (_res.options & RES_DEBUG) {
 215:                     printf("truncated answer\n");
 216:                 }
 217:                 (void) close(sockFD);
 218:                 sockFD = -1;
 219:                 retry = _res.retry;
 220:                 v_circuit = 1;
 221:                 continue;
 222:             }
 223:         }
 224:         if (_res.options & RES_DEBUG) {
 225:             if (_res.options & RES_DEBUG2)
 226:             printf("Got answer:\n");
 227:             Print_query(answer, answer+resplen, 0);
 228:         }
 229:         (void) close(sockFD);
 230:         sockFD = -1;
 231:         *trueLenPtr = resplen;
 232:         return (SUCCESS);
 233:     }
 234:     (void) close(sockFD);
 235:     sockFD = -1;
 236:     return (TIME_OUT);
 237: }

Defined functions

Defined variables

sccsid defined in line 18; never used
sin defined in line 34; used 6 times
Last modified: 1986-04-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1372
Valid CSS Valid XHTML 1.0 Strict