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 | | - | |