mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-04 13:48:30 +00:00
Compare commits
5
Commits
v2.93test4
...
v2.93test6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65adc53130 | ||
|
|
66d9658f5f | ||
|
|
ca30c82647 | ||
|
|
32a54fc8a5 | ||
|
|
3f2bfca3df |
No files matched your search
@@ -28,6 +28,12 @@ version 2.93
|
||||
relay is in use. Many thanks to Jørgen Søvik for help
|
||||
finding this bug.
|
||||
|
||||
Modify the inotify implementation so that inotify watches are
|
||||
only created after dnsmasq has changed permissions and userid.
|
||||
This means that the permissions used when creating the watches
|
||||
are the same as used for accessing watched files, which makes
|
||||
more sense and avoids odd and confusing error conditions.
|
||||
|
||||
|
||||
version 2.92
|
||||
Redesign the interaction between DNSSEC validation and per-domain
|
||||
|
||||
+7
-7
@@ -591,7 +591,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
if (auth && zone)
|
||||
{
|
||||
char *authname;
|
||||
int newoffset, offset = 0;
|
||||
int newoffset = ansp - (unsigned char *)header, offset = 0;
|
||||
|
||||
if (!subnet)
|
||||
authname = zone->domain;
|
||||
@@ -631,8 +631,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
}
|
||||
|
||||
/* handle NS and SOA in auth section or for explicit queries */
|
||||
newoffset = ansp - (unsigned char *)header;
|
||||
if (((anscount == 0 && !ns) || soa) &&
|
||||
if (((anscount == 0 && !ns) || soa) &&
|
||||
add_resource_record(header, limit, &trunc, 0, &ansp,
|
||||
daemon->auth_ttl, NULL, T_SOA, C_IN, "ddlllll",
|
||||
authname, daemon->authserver, daemon->hostmaster,
|
||||
@@ -650,11 +649,10 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
if (anscount != 0 || ns)
|
||||
{
|
||||
struct name_list *secondary;
|
||||
|
||||
|
||||
/* Only include the machine running dnsmasq if it's acting as an auth server */
|
||||
if (daemon->authinterface)
|
||||
{
|
||||
newoffset = ansp - (unsigned char *)header;
|
||||
if (add_resource_record(header, limit, &trunc, -offset, &ansp,
|
||||
daemon->auth_ttl, NULL, T_NS, C_IN, "d", offset == 0 ? authname : NULL, daemon->authserver))
|
||||
{
|
||||
@@ -669,9 +667,11 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
|
||||
if (!subnet)
|
||||
for (secondary = daemon->secondary_forward_server; secondary; secondary = secondary->next)
|
||||
if (add_resource_record(header, limit, &trunc, offset, &ansp,
|
||||
daemon->auth_ttl, NULL, T_NS, C_IN, "d", secondary->name))
|
||||
if (add_resource_record(header, limit, &trunc, -offset, &ansp,
|
||||
daemon->auth_ttl, NULL, T_NS, C_IN, "d", offset == 0 ? authname : NULL, secondary->name))
|
||||
{
|
||||
if (offset == 0)
|
||||
offset = newoffset;
|
||||
if (ns)
|
||||
anscount++;
|
||||
else
|
||||
|
||||
+1
-1
@@ -1600,7 +1600,7 @@ void cache_reload(void)
|
||||
|
||||
#ifdef HAVE_DNSSEC
|
||||
for (ds = daemon->ds; ds; ds = ds->next)
|
||||
if ((cache = get_config_crec()))
|
||||
if (ds->name && (cache = get_config_crec()))
|
||||
{
|
||||
|
||||
if (!(cache->addr.ds.keydata = blockdata_alloc(ds->digest, ds->digestlen)))
|
||||
|
||||
+49
-11
@@ -437,14 +437,6 @@ int main (int argc, char **argv)
|
||||
daemon->tcp_pipes[i] = -1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_INOTIFY
|
||||
if ((daemon->port != 0 && !option_bool(OPT_NO_RESOLV)) ||
|
||||
daemon->dynamic_dirs)
|
||||
inotify_dnsmasq_init();
|
||||
else
|
||||
daemon->inotifyfd = -1;
|
||||
#endif
|
||||
|
||||
if (daemon->dump_file)
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_init();
|
||||
@@ -864,6 +856,14 @@ int main (int argc, char **argv)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_INOTIFY
|
||||
if ((daemon->port != 0 && !option_bool(OPT_NO_RESOLV)) ||
|
||||
daemon->dynamic_dirs)
|
||||
inotify_dnsmasq_init(err_pipe[1]);
|
||||
else
|
||||
daemon->inotifyfd = -1;
|
||||
#endif
|
||||
|
||||
/* Don't start logging malloc before logging is set up. */
|
||||
daemon->log_malloc = option_bool(OPT_LOG_MALLOC);
|
||||
|
||||
@@ -946,9 +946,27 @@ int main (int argc, char **argv)
|
||||
my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until system time valid"));
|
||||
|
||||
for (ds = daemon->ds; ds; ds = ds->next)
|
||||
my_syslog(LOG_INFO,
|
||||
ds->digestlen == 0 ? _("configured with negative trust anchor for %s") : _("configured with trust anchor for %s keytag %u"),
|
||||
ds->name[0] == 0 ? "<root>" : ds->name, ds->keytag);
|
||||
{
|
||||
struct ds_config *ds1;
|
||||
|
||||
for (ds1 = ds->next; ds1; ds1 = ds1->next)
|
||||
if (strcmp(ds->name, ds1->name) == 0 &&
|
||||
ds->digestlen == ds1->digestlen &&
|
||||
(ds->digestlen == 0 ||
|
||||
(ds->algo == ds1->algo &&
|
||||
ds->keytag == ds1->keytag &&
|
||||
ds->digest_type == ds1->digest_type &&
|
||||
memcmp(ds->digest, ds1->digest, ds->digestlen) == 0)))
|
||||
{
|
||||
ds->name = NULL; /* Mark as duplicate */
|
||||
break;
|
||||
}
|
||||
|
||||
if (ds->name)
|
||||
my_syslog(LOG_INFO,
|
||||
ds->digestlen == 0 ? _("configured with negative trust anchor for %s") : _("configured with trust anchor for %s keytag %u"),
|
||||
ds->name[0] == 0 ? "<root>" : ds->name, ds->keytag);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1527,6 +1545,26 @@ static void fatal_event(struct event_desc *ev, char *msg)
|
||||
/* fall through */
|
||||
case EVENT_TIME_ERR:
|
||||
die(_("cannot create timestamp file %s: %s" ), msg, EC_BADCONF);
|
||||
|
||||
/* fall through */
|
||||
case EVENT_LINK_ERR:
|
||||
die(_("cannot access path %s: %s" ), msg, EC_MISC);
|
||||
|
||||
/* fall through */
|
||||
case EVENT_INOTFY_ERR:
|
||||
die(_("failed to create inotify: %s" ), NULL, EC_MISC);
|
||||
|
||||
/* fall through */
|
||||
case EVENT_TMSL_ERR:
|
||||
die(_("too many symlinks following %s"), msg, EC_MISC);
|
||||
|
||||
/* fall through */
|
||||
case EVENT_RESOLV_ERR:
|
||||
die(_("directory %s for resolv-file is missing, cannot poll"), msg, EC_MISC);
|
||||
|
||||
/* fall through */
|
||||
case EVENT_IFILE_ERR:
|
||||
die(_("failed to create inotify for %s: %s"), msg, EC_MISC);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-1
@@ -201,6 +201,11 @@ struct event_desc {
|
||||
#define EVENT_TIME_ERR 24
|
||||
#define EVENT_SCRIPT_LOG 25
|
||||
#define EVENT_TIME 26
|
||||
#define EVENT_LINK_ERR 27
|
||||
#define EVENT_INOTFY_ERR 28
|
||||
#define EVENT_TMSL_ERR 29
|
||||
#define EVENT_RESOLV_ERR 30
|
||||
#define EVENT_IFILE_ERR 31
|
||||
|
||||
/* Exit codes. */
|
||||
#define EC_GOOD 0
|
||||
@@ -1497,11 +1502,13 @@ unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit);
|
||||
void *safe_malloc(size_t size);
|
||||
void safe_strncpy(char *dest, const char *src, size_t size);
|
||||
void safe_pipe(int *fd, int read_noblock);
|
||||
#define malloc_log(x, y) malloc_log_real(__func__, __LINE__, (x), (y))
|
||||
#define whine_malloc(x) whine_malloc_real(__func__, __LINE__, (x))
|
||||
#define whine_realloc(x, y) whine_realloc_real(NULL, __func__, __LINE__, (x), (y))
|
||||
#define expand_buf(x, y) expand_buf_real(__func__, __LINE__, (x), (y))
|
||||
#define expand_workspace(x, y, z) expand_workspace_real(__func__, __LINE__, (x), (y), (z))
|
||||
#define free(x) free_real(__func__, __LINE__, (x))
|
||||
void malloc_log_real(const char *func, unsigned int line, void *mem, size_t size);
|
||||
void free_real(const char *func, unsigned int line, void *ptr);
|
||||
void *whine_malloc_real(const char *func, unsigned int line, size_t size);
|
||||
void *whine_realloc_real(const char *wrapper, const char *func, unsigned int line, void *ptr, size_t size);
|
||||
@@ -1905,7 +1912,7 @@ int detect_loop(char *query, int type);
|
||||
|
||||
/* inotify.c */
|
||||
#ifdef HAVE_INOTIFY
|
||||
void inotify_dnsmasq_init(void);
|
||||
void inotify_dnsmasq_init(int errfd);
|
||||
int inotify_check(time_t now);
|
||||
void set_dynamic_inotify(int flag, int total_size, struct crec **rhash, int revhashsz);
|
||||
#endif
|
||||
|
||||
+25
-10
@@ -40,7 +40,7 @@ static char *inotify_buffer;
|
||||
points to, made absolute if relative.
|
||||
If path doesn't exist or is not a symlink, return NULL.
|
||||
Return value is malloc'ed */
|
||||
static char *my_readlink(char *path)
|
||||
static char *my_readlink(int errfd, char *path)
|
||||
{
|
||||
ssize_t rc, size = 64;
|
||||
char *buf;
|
||||
@@ -59,7 +59,10 @@ static char *my_readlink(char *path)
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
die(_("cannot access path %s: %s"), path, EC_MISC);
|
||||
{
|
||||
send_event(errfd, EVENT_LINK_ERR, errno, path);
|
||||
_exit(0);
|
||||
}
|
||||
}
|
||||
else if (rc < size-1)
|
||||
{
|
||||
@@ -85,15 +88,18 @@ static char *my_readlink(char *path)
|
||||
}
|
||||
}
|
||||
|
||||
void inotify_dnsmasq_init()
|
||||
void inotify_dnsmasq_init(int errfd)
|
||||
{
|
||||
struct resolvc *res;
|
||||
inotify_buffer = safe_malloc(INOTIFY_SZ);
|
||||
daemon->inotifyfd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
|
||||
|
||||
if (daemon->inotifyfd == -1)
|
||||
die(_("failed to create inotify: %s"), NULL, EC_MISC);
|
||||
|
||||
{
|
||||
send_event(errfd, EVENT_INOTFY_ERR, errno, NULL);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
if (daemon->port == 0 || option_bool(OPT_NO_RESOLV))
|
||||
return;
|
||||
|
||||
@@ -105,10 +111,13 @@ void inotify_dnsmasq_init()
|
||||
strcpy(path, res->name);
|
||||
|
||||
/* Follow symlinks until we reach a non-symlink, or a non-existent file. */
|
||||
while ((new_path = my_readlink(path)))
|
||||
while ((new_path = my_readlink(errfd, path)))
|
||||
{
|
||||
if (links-- == 0)
|
||||
die(_("too many symlinks following %s"), res->name, EC_MISC);
|
||||
{
|
||||
send_event(errfd, EVENT_TMSL_ERR, 0, res->name);
|
||||
_exit(0);
|
||||
}
|
||||
free(path);
|
||||
path = new_path;
|
||||
}
|
||||
@@ -124,12 +133,18 @@ void inotify_dnsmasq_init()
|
||||
*d = '/';
|
||||
|
||||
if (res->wd == -1 && errno == ENOENT)
|
||||
die(_("directory %s for resolv-file is missing, cannot poll"), res->name, EC_MISC);
|
||||
{
|
||||
send_event(errfd, EVENT_RESOLV_ERR, 0, res->name);
|
||||
_exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (res->wd == -1)
|
||||
die(_("failed to create inotify for %s: %s"), res->name, EC_MISC);
|
||||
|
||||
{
|
||||
send_event(errfd, EVENT_IFILE_ERR, errno, res->name);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1427,6 +1427,11 @@ int check_for_ignored_address(struct dns_header *header, size_t qlen)
|
||||
return check_bad_address(header, qlen, daemon->ignore_addr, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Nameoffset > 0 means that the name of the new record already exists at the given offset,
|
||||
so use a "jump" to that.
|
||||
Nameoffset == 0 means use the first variable argument as the name of the new record.
|
||||
nameoffset < 0 means use the first variable argument as the start of the new record name,
|
||||
then "jump" to -nameoffset to complete it. */
|
||||
int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp,
|
||||
unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...)
|
||||
{
|
||||
|
||||
+15
-3
@@ -266,6 +266,10 @@ char *canonicalise(char *in, int *nomem)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* IDN library doesnt call our malloc wrapper, so log this by steam */
|
||||
if (ret)
|
||||
malloc_log(ret, strlen(ret)+1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -323,13 +327,15 @@ void *safe_malloc(size_t size)
|
||||
}
|
||||
|
||||
/* Ensure limited size string is always terminated.
|
||||
* Can be replaced by (void)strlcpy() on some platforms */
|
||||
Can be replaced by (void)strlcpy() on some platforms.
|
||||
src may be NULL in which case we return an empty string. */
|
||||
void safe_strncpy(char *dest, const char *src, size_t size)
|
||||
{
|
||||
if (size != 0)
|
||||
{
|
||||
dest[size-1] = '\0';
|
||||
strncpy(dest, src, size-1);
|
||||
dest[0] = dest[size-1] = '\0';
|
||||
if (src)
|
||||
strncpy(dest, src, size-1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -993,6 +999,12 @@ int expand_workspace_real(const char *func, unsigned int line, unsigned char ***
|
||||
return 1;
|
||||
}
|
||||
|
||||
void malloc_log_real(const char *func, unsigned int line, void *mem, size_t size)
|
||||
{
|
||||
if (mem && daemon->log_malloc)
|
||||
my_syslog(LOG_INFO, _("malloc: %s:%u %zu bytes at %x"), func, line, size, hash_ptr(mem));
|
||||
}
|
||||
|
||||
#undef free
|
||||
void free_real(const char *func, unsigned int line, void *ptr)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user