Annotation of 43BSD/etc/named/tools/ns.lookup/src/send.c, revision 1.1

1.1     ! root        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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.