Configurable hosts path for file_lookup (#465)

This changeset adds support for configurable hosts file
ARES_OPT_HOSTS_FILE (similar to ARES_OPT_RESOLVCONF).

Co-authored-by: Manish Mehra (@mmehra)
pull/467/head
Manish Mehra 3 years ago committed by GitHub
parent e01dbc6541
commit 810c2322f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 11
      docs/ares_init_options.3
  2. 2
      include/ares.h
  3. 5
      src/lib/ares_destroy.c
  4. 5
      src/lib/ares_getaddrinfo.c
  5. 26
      src/lib/ares_init.c
  6. 3
      src/lib/ares_private.h
  7. 31
      test/ares-test-init.cc

@ -41,6 +41,7 @@ struct ares_options {
int nsort;
int ednspsz;
char *resolvconf_path;
char *hosts_path;
};
int ares_init_options(ares_channel *\fIchannelptr\fP,
@ -195,6 +196,16 @@ should be set to a path string, and will be honoured on *nix like systems. The
default is
.B /etc/resolv.conf
.br
.TP 18
.B ARES_OPT_HOSTS_FILE
.B char *\fIhosts_path\fP;
.br
The path to use for reading the hosts file. The
.I hosts_path
should be set to a path string, and will be honoured on *nix like systems. The
default is
.B /etc/hosts
.br
.PP
The \fIoptmask\fP parameter also includes options without a corresponding
field in the

@ -175,6 +175,7 @@ extern "C" {
#define ARES_OPT_EDNSPSZ (1 << 15)
#define ARES_OPT_NOROTATE (1 << 16)
#define ARES_OPT_RESOLVCONF (1 << 17)
#define ARES_OPT_HOSTS_FILE (1 << 18)
/* Nameinfo flag values */
#define ARES_NI_NOFQDN (1 << 0)
@ -284,6 +285,7 @@ struct ares_options {
int nsort;
int ednspsz;
char *resolvconf_path;
char *hosts_path;
};
struct hostent;

@ -38,6 +38,8 @@ void ares_destroy_options(struct ares_options *options)
ares_free(options->lookups);
if(options->resolvconf_path)
ares_free(options->resolvconf_path);
if(options->hosts_path)
ares_free(options->hosts_path);
}
void ares_destroy(ares_channel channel)
@ -90,6 +92,9 @@ void ares_destroy(ares_channel channel)
if (channel->resolvconf_path)
ares_free(channel->resolvconf_path);
if (channel->hosts_path)
ares_free(channel->hosts_path);
ares_free(channel);
}

@ -416,6 +416,11 @@ static int file_lookup(struct host_query *hquery)
path_hosts = getenv("CARES_HOSTS");
}
if (hquery->channel->hosts_path)
{
path_hosts = hquery->channel->hosts_path;
}
if (!path_hosts)
{
#ifdef WIN32

@ -164,6 +164,7 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
channel->sock_funcs = NULL;
channel->sock_func_cb_data = NULL;
channel->resolvconf_path = NULL;
channel->hosts_path = NULL;
channel->last_server = 0;
channel->last_timeout_processed = (time_t)now.tv_sec;
@ -239,6 +240,8 @@ done:
ares_free(channel->lookups);
if(channel->resolvconf_path)
ares_free(channel->resolvconf_path);
if(channel->hosts_path)
ares_free(channel->hosts_path);
ares_free(channel);
return status;
}
@ -350,6 +353,9 @@ int ares_save_options(ares_channel channel, struct ares_options *options,
if (channel->resolvconf_path)
(*optmask) |= ARES_OPT_RESOLVCONF;
if (channel->hosts_path)
(*optmask) |= ARES_OPT_HOSTS_FILE;
/* Copy easy stuff */
options->flags = channel->flags;
@ -429,6 +435,13 @@ int ares_save_options(ares_channel channel, struct ares_options *options,
return ARES_ENOMEM;
}
/* copy path for hosts file */
if (channel->hosts_path) {
options->hosts_path = ares_strdup(channel->hosts_path);
if (!options->hosts_path)
return ARES_ENOMEM;
}
return ARES_SUCCESS;
}
@ -545,6 +558,14 @@ static int init_by_options(ares_channel channel,
return ARES_ENOMEM;
}
/* Set path for hosts file, if given. */
if ((optmask & ARES_OPT_HOSTS_FILE) && !channel->hosts_path)
{
channel->hosts_path = ares_strdup(options->hosts_path);
if (!channel->hosts_path && options->hosts_path)
return ARES_ENOMEM;
}
channel->optmask = optmask;
return ARES_SUCCESS;
@ -1661,6 +1682,11 @@ static int init_by_defaults(ares_channel channel)
ares_free(channel->resolvconf_path);
channel->resolvconf_path = NULL;
}
if(channel->hosts_path) {
ares_free(channel->hosts_path);
channel->hosts_path = NULL;
}
}
if(hostname)

@ -339,6 +339,9 @@ struct ares_channeldata {
/* Path for resolv.conf file, configurable via ares_options */
char *resolvconf_path;
/* Path for hosts file, configurable via ares_options */
char *hosts_path;
};
/* Does the domain end in ".onion" or ".onion."? Case-insensitive. */

@ -88,6 +88,8 @@ TEST_F(LibraryTest, OptionsChannelInit) {
optmask |= ARES_OPT_ROTATE;
opts.resolvconf_path = strdup("/etc/resolv.conf");
optmask |= ARES_OPT_RESOLVCONF;
opts.hosts_path = strdup("/etc/hosts");
optmask |= ARES_OPT_HOSTS_FILE;
ares_channel channel = nullptr;
EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask));
@ -115,6 +117,7 @@ TEST_F(LibraryTest, OptionsChannelInit) {
EXPECT_EQ(std::string(opts.domains[1]), std::string(opts2.domains[1]));
EXPECT_EQ(std::string(opts.lookups), std::string(opts2.lookups));
EXPECT_EQ(std::string(opts.resolvconf_path), std::string(opts2.resolvconf_path));
EXPECT_EQ(std::string(opts.hosts_path), std::string(opts2.hosts_path));
ares_destroy_options(&opts);
ares_destroy_options(&opts2);
@ -174,6 +177,8 @@ TEST_F(LibraryTest, OptionsChannelAllocFail) {
optmask |= ARES_OPT_ROTATE;
opts.resolvconf_path = strdup("/etc/resolv.conf");
optmask |= ARES_OPT_RESOLVCONF;
opts.hosts_path = strdup("/etc/hosts");
optmask |= ARES_OPT_HOSTS_FILE;
ares_channel channel = nullptr;
for (int ii = 1; ii <= 8; ii++) {
@ -430,6 +435,32 @@ CONTAINED_TEST_F(LibraryTest, ContainerMyResolvConfInit,
return HasFailure();
}
// Allow hosts path to be configurable
NameContentList myhosts = {
{"/tmp/hosts", "10.0.12.26 foobar\n"
"2001:A0:C::1A foobar\n"}};
CONTAINED_TEST_F(LibraryTest, ContainerMyHostsInit,
"myhostname", "mydomain.org", myhosts) {
char filename[] = "/tmp/hosts";
ares_channel channel = nullptr;
struct ares_options options = {0};
options.hosts_path = strdup(filename);
int optmask = ARES_OPT_HOSTS_FILE;
EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &options, optmask));
optmask = 0;
free(options.hosts_path);
options.hosts_path = NULL;
EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel, &options, &optmask));
EXPECT_EQ(ARES_OPT_HOSTS_FILE, (optmask & ARES_OPT_HOSTS_FILE));
EXPECT_EQ(std::string(filename), std::string(options.hosts_path));
ares_destroy_options(&options);
ares_destroy(channel);
return HasFailure();
}
NameContentList hostconf = {
{"/etc/resolv.conf", "nameserver 1.2.3.4\n"
"sortlist1.2.3.4\n" // malformed line

Loading…
Cancel
Save