mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-13 17:00:49 +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
|
relay is in use. Many thanks to Jørgen Søvik for help
|
||||||
finding this bug.
|
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
|
version 2.92
|
||||||
Redesign the interaction between DNSSEC validation and per-domain
|
Redesign the interaction between DNSSEC validation and per-domain
|
||||||
|
|||||||
+6
-6
@@ -591,7 +591,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
if (auth && zone)
|
if (auth && zone)
|
||||||
{
|
{
|
||||||
char *authname;
|
char *authname;
|
||||||
int newoffset, offset = 0;
|
int newoffset = ansp - (unsigned char *)header, offset = 0;
|
||||||
|
|
||||||
if (!subnet)
|
if (!subnet)
|
||||||
authname = zone->domain;
|
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 */
|
/* 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,
|
add_resource_record(header, limit, &trunc, 0, &ansp,
|
||||||
daemon->auth_ttl, NULL, T_SOA, C_IN, "ddlllll",
|
daemon->auth_ttl, NULL, T_SOA, C_IN, "ddlllll",
|
||||||
authname, daemon->authserver, daemon->hostmaster,
|
authname, daemon->authserver, daemon->hostmaster,
|
||||||
@@ -654,7 +653,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
/* Only include the machine running dnsmasq if it's acting as an auth server */
|
/* Only include the machine running dnsmasq if it's acting as an auth server */
|
||||||
if (daemon->authinterface)
|
if (daemon->authinterface)
|
||||||
{
|
{
|
||||||
newoffset = ansp - (unsigned char *)header;
|
|
||||||
if (add_resource_record(header, limit, &trunc, -offset, &ansp,
|
if (add_resource_record(header, limit, &trunc, -offset, &ansp,
|
||||||
daemon->auth_ttl, NULL, T_NS, C_IN, "d", offset == 0 ? authname : NULL, daemon->authserver))
|
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)
|
if (!subnet)
|
||||||
for (secondary = daemon->secondary_forward_server; secondary; secondary = secondary->next)
|
for (secondary = daemon->secondary_forward_server; secondary; secondary = secondary->next)
|
||||||
if (add_resource_record(header, limit, &trunc, offset, &ansp,
|
if (add_resource_record(header, limit, &trunc, -offset, &ansp,
|
||||||
daemon->auth_ttl, NULL, T_NS, C_IN, "d", secondary->name))
|
daemon->auth_ttl, NULL, T_NS, C_IN, "d", offset == 0 ? authname : NULL, secondary->name))
|
||||||
{
|
{
|
||||||
|
if (offset == 0)
|
||||||
|
offset = newoffset;
|
||||||
if (ns)
|
if (ns)
|
||||||
anscount++;
|
anscount++;
|
||||||
else
|
else
|
||||||
|
|||||||
+1
-1
@@ -1600,7 +1600,7 @@ void cache_reload(void)
|
|||||||
|
|
||||||
#ifdef HAVE_DNSSEC
|
#ifdef HAVE_DNSSEC
|
||||||
for (ds = daemon->ds; ds; ds = ds->next)
|
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)))
|
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;
|
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)
|
if (daemon->dump_file)
|
||||||
#ifdef HAVE_DUMPFILE
|
#ifdef HAVE_DUMPFILE
|
||||||
dump_init();
|
dump_init();
|
||||||
@@ -864,6 +856,14 @@ int main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
#endif
|
#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. */
|
/* Don't start logging malloc before logging is set up. */
|
||||||
daemon->log_malloc = option_bool(OPT_LOG_MALLOC);
|
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"));
|
my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until system time valid"));
|
||||||
|
|
||||||
for (ds = daemon->ds; ds; ds = ds->next)
|
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"),
|
struct ds_config *ds1;
|
||||||
ds->name[0] == 0 ? "<root>" : ds->name, ds->keytag);
|
|
||||||
|
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
|
#endif
|
||||||
|
|
||||||
@@ -1527,6 +1545,26 @@ static void fatal_event(struct event_desc *ev, char *msg)
|
|||||||
/* fall through */
|
/* fall through */
|
||||||
case EVENT_TIME_ERR:
|
case EVENT_TIME_ERR:
|
||||||
die(_("cannot create timestamp file %s: %s" ), msg, EC_BADCONF);
|
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_TIME_ERR 24
|
||||||
#define EVENT_SCRIPT_LOG 25
|
#define EVENT_SCRIPT_LOG 25
|
||||||
#define EVENT_TIME 26
|
#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. */
|
/* Exit codes. */
|
||||||
#define EC_GOOD 0
|
#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_malloc(size_t size);
|
||||||
void safe_strncpy(char *dest, const char *src, size_t size);
|
void safe_strncpy(char *dest, const char *src, size_t size);
|
||||||
void safe_pipe(int *fd, int read_noblock);
|
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_malloc(x) whine_malloc_real(__func__, __LINE__, (x))
|
||||||
#define whine_realloc(x, y) whine_realloc_real(NULL, __func__, __LINE__, (x), (y))
|
#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_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 expand_workspace(x, y, z) expand_workspace_real(__func__, __LINE__, (x), (y), (z))
|
||||||
#define free(x) free_real(__func__, __LINE__, (x))
|
#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 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_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);
|
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 */
|
/* inotify.c */
|
||||||
#ifdef HAVE_INOTIFY
|
#ifdef HAVE_INOTIFY
|
||||||
void inotify_dnsmasq_init(void);
|
void inotify_dnsmasq_init(int errfd);
|
||||||
int inotify_check(time_t now);
|
int inotify_check(time_t now);
|
||||||
void set_dynamic_inotify(int flag, int total_size, struct crec **rhash, int revhashsz);
|
void set_dynamic_inotify(int flag, int total_size, struct crec **rhash, int revhashsz);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+23
-8
@@ -40,7 +40,7 @@ static char *inotify_buffer;
|
|||||||
points to, made absolute if relative.
|
points to, made absolute if relative.
|
||||||
If path doesn't exist or is not a symlink, return NULL.
|
If path doesn't exist or is not a symlink, return NULL.
|
||||||
Return value is malloc'ed */
|
Return value is malloc'ed */
|
||||||
static char *my_readlink(char *path)
|
static char *my_readlink(int errfd, char *path)
|
||||||
{
|
{
|
||||||
ssize_t rc, size = 64;
|
ssize_t rc, size = 64;
|
||||||
char *buf;
|
char *buf;
|
||||||
@@ -59,7 +59,10 @@ static char *my_readlink(char *path)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else
|
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)
|
else if (rc < size-1)
|
||||||
{
|
{
|
||||||
@@ -85,14 +88,17 @@ static char *my_readlink(char *path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void inotify_dnsmasq_init()
|
void inotify_dnsmasq_init(int errfd)
|
||||||
{
|
{
|
||||||
struct resolvc *res;
|
struct resolvc *res;
|
||||||
inotify_buffer = safe_malloc(INOTIFY_SZ);
|
inotify_buffer = safe_malloc(INOTIFY_SZ);
|
||||||
daemon->inotifyfd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
|
daemon->inotifyfd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
|
||||||
|
|
||||||
if (daemon->inotifyfd == -1)
|
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))
|
if (daemon->port == 0 || option_bool(OPT_NO_RESOLV))
|
||||||
return;
|
return;
|
||||||
@@ -105,10 +111,13 @@ void inotify_dnsmasq_init()
|
|||||||
strcpy(path, res->name);
|
strcpy(path, res->name);
|
||||||
|
|
||||||
/* Follow symlinks until we reach a non-symlink, or a non-existent file. */
|
/* 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)
|
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);
|
free(path);
|
||||||
path = new_path;
|
path = new_path;
|
||||||
}
|
}
|
||||||
@@ -124,11 +133,17 @@ void inotify_dnsmasq_init()
|
|||||||
*d = '/';
|
*d = '/';
|
||||||
|
|
||||||
if (res->wd == -1 && errno == ENOENT)
|
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)
|
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);
|
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,
|
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, ...)
|
unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...)
|
||||||
{
|
{
|
||||||
|
|||||||
+15
-3
@@ -267,6 +267,10 @@ char *canonicalise(char *in, int *nomem)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* IDN library doesnt call our malloc wrapper, so log this by steam */
|
||||||
|
if (ret)
|
||||||
|
malloc_log(ret, strlen(ret)+1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@@ -323,13 +327,15 @@ void *safe_malloc(size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure limited size string is always terminated.
|
/* 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)
|
void safe_strncpy(char *dest, const char *src, size_t size)
|
||||||
{
|
{
|
||||||
if (size != 0)
|
if (size != 0)
|
||||||
{
|
{
|
||||||
dest[size-1] = '\0';
|
dest[0] = dest[size-1] = '\0';
|
||||||
strncpy(dest, src, size-1);
|
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;
|
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
|
#undef free
|
||||||
void free_real(const char *func, unsigned int line, void *ptr)
|
void free_real(const char *func, unsigned int line, void *ptr)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user