- output[4] = header->qdcount / 256;
- output[5] = header->qdcount % 256;
- output[6] = header->ancount / 256;
- output[7] = header->ancount % 256;
- output[8] = header->nscount / 256;
- output[9] = header->nscount % 256;
- output[10] = header->arcount / 256;
- output[11] = header->arcount % 256;
- memcpy(&output[12],header->payload,l);
-}
-
-void dns_close(int fd) { /* close query */
- log(DEBUG,"DNS: dns_close on fd %d",fd);
- if (fd == lastcreate) {
- wantclose = 1;
- return;
- }
- shutdown(fd,2);
- close(fd);
- return;
-}
-
-void DNS::dns_init() { /* on first call only: populates servers4 struct with up to DNS_MAX nameserver IP addresses from /etc/resolv.conf */
- FILE *f;
- int i;
- in_addr addr4;
- char buf[1024];
- if (initdone == 1)
- return;
- i4 = 0;
-
- initdone = 1;
- srand((unsigned int) TIME);
- memset(servers4,'\0',sizeof(in_addr) * DNS_MAX);
- f = fopen(DNS_CONFIG_FBCK,"r");
- if (f == NULL)
- return;
- while (fgets(buf,1024,f) != NULL) {
- if (strncmp(buf,"nameserver",10) == 0) {
- i = 10;
- while (buf[i] == ' ' || buf[i] == '\t')
- i++;
- if (i4 < DNS_MAX) {
- if (dns_aton4_s(&buf[i],&addr4) != NULL)
- memcpy(&servers4[i4++],&addr4,sizeof(in_addr));
+ output[4] = header->qdcount >> 8;
+ output[5] = header->qdcount & 0xFF;
+ output[6] = header->ancount >> 8;
+ output[7] = header->ancount & 0xFF;
+ output[8] = header->nscount >> 8;
+ output[9] = header->nscount & 0xFF;
+ output[10] = header->arcount >> 8;
+ output[11] = header->arcount & 0xFF;
+ memcpy(&output[12],header->payload,length);
+}
+
+/** Send requests we have previously built down the UDP socket */
+int DNSRequest::SendRequests(const DNSHeader *header, const int length, QueryType qt)
+{
+ ServerInstance->Logs->Log("RESOLVER", DEBUG,"DNSRequest::SendRequests");
+
+ unsigned char payload[sizeof(DNSHeader)];
+
+ this->rr_class = 1;
+ this->type = qt;
+
+ DNS::EmptyHeader(payload,header,length);
+
+ if (ServerInstance->SE->SendTo(dnsobj, payload, length + 12, 0, &(dnsobj->myserver.sa), sa_size(dnsobj->myserver)) != length+12)
+ return -1;
+
+ ServerInstance->Logs->Log("RESOLVER",DEBUG,"Sent OK");
+ return 0;
+}
+
+/** Add a query with a predefined header, and allocate an ID for it. */
+DNSRequest* DNS::AddQuery(DNSHeader *header, int &id, const char* original)
+{
+ /* Is the DNS connection down? */
+ if (this->GetFd() == -1)
+ return NULL;
+
+ /* Create an id */
+ unsigned int tries = 0;
+ do {
+ id = ServerInstance->GenRandomInt(DNS::MAX_REQUEST_ID);
+ if (++tries == DNS::MAX_REQUEST_ID*5)
+ {
+ // If we couldn't find an empty slot this many times, do a sequential scan as a last
+ // resort. If an empty slot is found that way, go on, otherwise throw an exception
+ id = -1;
+ for (int i = 0; i < DNS::MAX_REQUEST_ID; i++)
+ {
+ if (!requests[i])
+ {
+ id = i;
+ break;
+ }