Files
FTL/resolve.c
T

129 lines
3.2 KiB
C

/* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* FTL Engine
* DNS Client Implementation
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
#include "FTL.h"
char *resolveHostname(const char *addr)
{
// Get host name
struct hostent *he = NULL;
char *hostname = NULL;;
bool IPv6 = false;
// Check if this is a hidden client
// if so, return "hidden" as hostname
if(strcmp(addr, "0.0.0.0") == 0)
{
hostname = strdup("hidden");
//if(hostname == NULL) return NULL;
return hostname;
}
// Test if we want to resolve an IPv6 address
if(strstr(addr,":") != NULL)
{
IPv6 = true;
}
if(IPv6 && config.resolveIPv6) // Resolve IPv6 address only if requested
{
struct in6_addr ipaddr;
inet_pton(AF_INET6, addr, &ipaddr);
he = gethostbyaddr(&ipaddr, sizeof ipaddr, AF_INET6);
}
else if(!IPv6 && config.resolveIPv4) // Resolve IPv4 address only if requested
{
struct in_addr ipaddr;
inet_pton(AF_INET, addr, &ipaddr);
he = gethostbyaddr(&ipaddr, sizeof ipaddr, AF_INET);
}
if(he == NULL)
{
// No hostname found
hostname = strdup("");
//if(hostname == NULL) return NULL;
}
else
{
// Return hostname copied to new memory location
hostname = strdup(he->h_name);
if(hostname == NULL) return NULL;
// Convert hostname to lower case
strtolower(hostname);
}
return hostname;
}
// This routine is run *after* garbage cleaning (default interval is once per hour)
// to account for possibly updated hostnames
void reresolveHostnames(void)
{
int clientID;
for(clientID = 0; clientID < counters.clients; clientID++)
{
// Memory validation
validate_access("clients", clientID, true, __LINE__, __FUNCTION__, __FILE__);
// Process this client only if it has at least one active query in the log
if(clients[clientID].count < 1)
continue;
// Get client hostname
char *hostname = resolveHostname(clients[clientID].ip);
if(strlen(hostname) > 0)
{
// Delete possibly already existing hostname pointer before storing new data
if(clients[clientID].name != NULL)
{
free(clients[clientID].name);
clients[clientID].name = NULL;
}
// Store client hostname
clients[clientID].name = strdup(hostname);
}
free(hostname);
}
}
// This routine is run *before* saving to the database (default interval is once per minute)
// to account for new clients (and forward destinations)
void resolveNewClients(void)
{
int i;
for(i = 0; i < counters.clients; i++)
{
// Memory validation
validate_access("clients", i, true, __LINE__, __FUNCTION__, __FILE__);
// Only try to resolve new clients
// Note that it can happen that we are not able to find hostnames but we don't
// want to try to resolve them every minute in this case.
if(clients[i].new)
{
clients[i].name = resolveHostname(clients[i].ip);
clients[i].new = false;
}
}
for(i = 0; i < counters.forwarded; i++)
{
// Memory validation
validate_access("forwarded", i, true, __LINE__, __FUNCTION__, __FILE__);
// Only try to resolve new forward destinations
if(forwarded[i].new)
{
forwarded[i].name = resolveHostname(forwarded[i].ip);
forwarded[i].new = false;
}
}
}