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