Skip to content

Commit

Permalink
Merge pull request #1826 from pi-hole/fix/resolver
Browse files Browse the repository at this point in the history
Improve and fix host name resolution
  • Loading branch information
DL6ER authored Jan 30, 2024
2 parents ce4407b + 4cbe8b4 commit 3262d7d
Show file tree
Hide file tree
Showing 9 changed files with 426 additions and 201 deletions.
22 changes: 22 additions & 0 deletions src/args.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
#include <idn2.h>
// sha256sum()
#include "files.h"
// resolveHostname()
#include "resolve.h"

// defined in dnsmasq.c
extern void print_dnsmasq_version(const char *yellow, const char *green, const char *bold, const char *normal);
Expand Down Expand Up @@ -496,6 +498,25 @@ void parse_args(int argc, char* argv[])
exit(EXIT_SUCCESS);
}

// Local reverse name resolver
if(argc == 3 && strcasecmp(argv[1], "ptr") == 0)
{
// Enable stdout printing
cli_mode = true;

// Need to get dns.port and the resolver settings
readFTLconf(&config, false);

char *name = resolveHostname(argv[2], true);
if(name == NULL)
exit(EXIT_FAILURE);

// Print result
printf("%s\n", name);
free(name);
exit(EXIT_SUCCESS);
}

// start from 1, as argv[0] is the executable name
for(int i = 1; i < argc; i++)
{
Expand Down Expand Up @@ -980,6 +1001,7 @@ void parse_args(int argc, char* argv[])
printf(" Decoding: %spihole-FTL idn2 -d %spunycode%s\n\n", green, cyan, normal);

printf("%sOther:%s\n", yellow, normal);
printf("\t%sptr %sIP%s Resolve IP address to hostname\n", green, cyan, normal);
printf("\t%ssha256sum %sfile%s Calculate SHA256 checksum of a file\n", green, cyan, normal);
printf("\t%sdhcp-discover%s Discover DHCP servers in the local\n", green, normal);
printf("\t network\n");
Expand Down
4 changes: 2 additions & 2 deletions src/config/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,8 @@ void initConfig(struct config *conf)
struct enum_options piholePTR[] =
{
{ get_ptr_type_str(PTR_NONE), "Pi-hole will not respond automatically on PTR requests to local interface addresses. Ensure pi.hole and/or hostname records exist elsewhere." },
{ get_ptr_type_str(PTR_HOSTNAME), "Pi-hole will not respond automatically on PTR requests to local interface addresses. Ensure pi.hole and/or hostname records exist elsewhere." },
{ get_ptr_type_str(PTR_HOSTNAMEFQDN), "Serve the machine's global hostname as fully qualified domain by adding the local suffix. If no local suffix has been defined, FTL appends the local domain .no_fqdn_available. In this case you should either add domain=whatever.com to a custom config file inside /etc/dnsmasq.d/ (to set whatever.com as local domain) or use domain=# which will try to derive the local domain from /etc/resolv.conf (or whatever is set with resolv-file, when multiple search directives exist, the first one is used)." },
{ get_ptr_type_str(PTR_HOSTNAME), "Serve the machine's hostname. The hostname is queried from the kernel through uname(2)->nodename. If the machine has multiple network interfaces, it can also have multiple nodenames. In this case, it is unspecified and up to the kernel which one will be returned. On Linux, the returned string is what has been set using sethostname(2) which is typically what has been set in /etc/hostname." },
{ get_ptr_type_str(PTR_HOSTNAMEFQDN), "Serve the machine's hostname (see limitations above) as fully qualified domain by adding the local domain. If no local domain has been defined (config option dns.domain), FTL tries to query the domain name from the kernel using getdomainname(2). If this fails, FTL appends \".no_fqdn_available\" to the hostname." },
{ get_ptr_type_str(PTR_PIHOLE), "Respond with \"pi.hole\"." }
};
CONFIG_ADD_ENUM_OPTIONS(conf->dns.piholePTR.a, piholePTR);
Expand Down
23 changes: 21 additions & 2 deletions src/daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,20 +178,39 @@ char *getUserName(void)
// hyphen.
#define HOSTNAMESIZE 256
static char nodename[HOSTNAMESIZE] = { 0 };
static char dname[HOSTNAMESIZE] = { 0 };

// Returns the hostname of the system
const char *hostname(void)
{
// Ask kernel for node name if not known
// This is equivalent to "uname -n"
//
// According to man gethostname(2), this is exactly the same as calling
// getdomainname() just with one step less
if(nodename[0] == '\0')
{
struct utsname buf;
if(uname(&buf) == 0)
{
strncpy(nodename, buf.nodename, HOSTNAMESIZE);
nodename[HOSTNAMESIZE-1] = '\0';
strncpy(dname, buf.domainname, HOSTNAMESIZE);
}
nodename[HOSTNAMESIZE - 1] = '\0';
dname[HOSTNAMESIZE - 1] = '\0';
}
return nodename;
}

// Returns the domain name of the system
const char *domainname(void)
{
if(dname[0] == '\0')
hostname();

return dname;
}

void delay_startup(void)
{
// Exit early if not sleeping
Expand Down Expand Up @@ -463,4 +482,4 @@ void init_locale(void)
// the dot as decimal separator (even if the system locale uses a
// comma, e.g., in German)
setlocale(LC_NUMERIC, "C");
}
}
1 change: 1 addition & 0 deletions src/daemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ void go_daemon(void);
void savepid(void);
char *getUserName(void);
const char *hostname(void);
const char *domainname(void);
void delay_startup(void);
bool is_fork(const pid_t mpid, const pid_t pid) __attribute__ ((const));
void cleanup(const int ret);
Expand Down
2 changes: 1 addition & 1 deletion src/database/network-table.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include "../datastructure.h"
// struct config
#include "../config/config.h"
// resolveHostname()
// resolve_this_name()
#include "../resolve.h"
// killed
#include "../signals.h"
Expand Down
8 changes: 7 additions & 1 deletion src/dnsmasq_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -2967,10 +2967,16 @@ static char *get_ptrname(struct in_addr *addr)
suffix = get_domain(*addr);
else
suffix = daemon->domain_suffix;

// If local suffix is not available, we try to obtain the domain from
// the kernel similar to how we do it for the hostname
if(!suffix)
suffix = (char*)domainname();

// If local suffix is not available, we substitute "no_fqdn_available"
// see the comment about PIHOLE_PTR=HOSTNAMEFQDN in the Pi-hole docs
// for further details on why this was chosen
if(!suffix)
if(!suffix || suffix[0] == '\0')
suffix = (char*)"no_fqdn_available";

// Get enough space for domain building
Expand Down
Loading

0 comments on commit 3262d7d

Please sign in to comment.