dnsmasq: backport --tftp-no-fail to ignore missing tftp root

This patch backports the option --tftp-no-fail to dnsmasq and prevents the
service from aborting if the specified TFTP root directory is not available;
this might be the case if TFTP files are located on external media that might
occasionally not be present at startup.

Signed-off-by: Stefan Tomanek <stefan.tomanek+openwrt@wertarbyte.de>

SVN-Revision: 45213
This commit is contained in:
John Crispin 2015-04-01 08:33:10 +00:00
parent 3ec7ccf501
commit 8acbb5783d
2 changed files with 194 additions and 0 deletions

View file

@ -128,6 +128,7 @@ dnsmasq() {
append_bool "$cfg" boguspriv "--bogus-priv"
append_bool "$cfg" expandhosts "--expand-hosts"
append_bool "$cfg" enable_tftp "--enable-tftp"
append_bool "$cfg" tftp_no_fail "--tftp-no-fail"
append_bool "$cfg" nonwildcard "--bind-interfaces"
append_bool "$cfg" fqdn "--dhcp-fqdn"
append_bool "$cfg" proxydnssec "--proxy-dnssec"

View file

@ -0,0 +1,193 @@
From 56920681eaf2c5eb08fc75baee4939d15d03b0ea Mon Sep 17 00:00:00 2001
From: Stefan Tomanek <stefan.tomanek+dnsmasq@wertarbyte.de>
Date: Tue, 31 Mar 2015 22:32:11 +0100
Subject: [PATCH] add --tftp-no-fail to ignore missing tftp root
(cherry picked from commit 30d0879ed55cb67b1b735beab3d93f3bb3ef1dd2)
Conflicts:
CHANGELOG
src/dnsmasq.c
src/dnsmasq.h
src/option.c
---
dnsmasq.conf.example | 3 +++
man/dnsmasq.8 | 3 +++
src/dnsmasq.c | 42 +++++++++++++++++++++++++++++++-----------
src/dnsmasq.h | 4 +++-
src/option.c | 3 +++
5 files changed, 43 insertions(+), 12 deletions(-)
diff --git a/dnsmasq.conf.example b/dnsmasq.conf.example
index 1bd305d..67be99a 100644
--- a/dnsmasq.conf.example
+++ b/dnsmasq.conf.example
@@ -486,6 +486,9 @@
# Set the root directory for files available via FTP.
#tftp-root=/var/ftpd
+# Do not abort if the tftp-root is unavailable
+#tftp-no-fail
+
# Make the TFTP server more secure: with this set, only files owned by
# the user dnsmasq is running as will be send over the net.
#tftp-secure
diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
index 0b8e04f..2ff4b96 100644
--- a/man/dnsmasq.8
+++ b/man/dnsmasq.8
@@ -1670,6 +1670,9 @@ Absolute paths (starting with /) are allowed, but they must be within
the tftp-root. If the optional interface argument is given, the
directory is only used for TFTP requests via that interface.
.TP
+.B --tftp-no-fail
+Do not abort startup if specified tftp root directories are inaccessible.
+.TP
.B --tftp-unique-root
Add the IP address of the TFTP client as a path component on the end
of the TFTP-root (in standard dotted-quad format). Only valid if a
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index 5c7750d..b6fa285 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -58,6 +58,9 @@ int main (int argc, char **argv)
struct dhcp_context *context;
struct dhcp_relay *relay;
#endif
+#ifdef HAVE_TFTP
+ int tftp_prefix_missing = 0;
+#endif
#ifdef LOCALEDIR
setlocale(LC_ALL, "");
@@ -623,7 +626,7 @@ int main (int argc, char **argv)
#endif
#ifdef HAVE_TFTP
- if (option_bool(OPT_TFTP))
+ if (option_bool(OPT_TFTP))
{
DIR *dir;
struct tftp_prefix *p;
@@ -632,24 +635,33 @@ int main (int argc, char **argv)
{
if (!((dir = opendir(daemon->tftp_prefix))))
{
- send_event(err_pipe[1], EVENT_TFTP_ERR, errno, daemon->tftp_prefix);
- _exit(0);
+ tftp_prefix_missing = 1;
+ if (!option_bool(OPT_TFTP_NO_FAIL))
+ {
+ send_event(err_pipe[1], EVENT_TFTP_ERR, errno, daemon->tftp_prefix);
+ _exit(0);
+ }
}
closedir(dir);
}
-
+
for (p = daemon->if_prefix; p; p = p->next)
{
+ p->missing = 0;
if (!((dir = opendir(p->prefix))))
- {
- send_event(err_pipe[1], EVENT_TFTP_ERR, errno, p->prefix);
- _exit(0);
- }
+ {
+ p->missing = 1;
+ if (!option_bool(OPT_TFTP_NO_FAIL))
+ {
+ send_event(err_pipe[1], EVENT_TFTP_ERR, errno, p->prefix);
+ _exit(0);
+ }
+ }
closedir(dir);
}
}
#endif
-
+
if (daemon->port == 0)
my_syslog(LOG_INFO, _("started, version %s DNS disabled"), VERSION);
else if (daemon->cachesize != 0)
@@ -743,8 +755,9 @@ int main (int argc, char **argv)
#endif
#ifdef HAVE_TFTP
- if (option_bool(OPT_TFTP))
- {
+ if (option_bool(OPT_TFTP))
+ {
+ struct tftp_prefix *p;
#ifdef FD_SETSIZE
if (FD_SETSIZE < (unsigned)max_fd)
max_fd = FD_SETSIZE;
@@ -754,7 +767,14 @@ int main (int argc, char **argv)
daemon->tftp_prefix ? _("root is ") : _("enabled"),
daemon->tftp_prefix ? daemon->tftp_prefix: "",
option_bool(OPT_TFTP_SECURE) ? _("secure mode") : "");
+
+ if (tftp_prefix_missing)
+ my_syslog(MS_TFTP | LOG_WARNING, _("warning: %s inaccessible"), daemon->tftp_prefix);
+ for (p = daemon->if_prefix; p; p = p->next)
+ if (p->missing)
+ my_syslog(MS_TFTP | LOG_WARNING, _("warning: TFTP directory %s inaccessible"), p->prefix);
+
/* This is a guess, it assumes that for small limits,
disjoint files might be served, but for large limits,
a single file will be sent to may clients (the file only needs
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 1dd61c5..086cb67 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -238,7 +238,8 @@ struct event_desc {
#define OPT_DNSSEC_NO_SIGN 48
#define OPT_LOCAL_SERVICE 49
#define OPT_LOOP_DETECT 50
-#define OPT_LAST 51
+#define OPT_TFTP_NO_FAIL 51
+#define OPT_LAST 52
/* extra flags for my_syslog, we use a couple of facilities since they are known
not to occupy the same bits as priorities, no matter how syslog.h is set up. */
@@ -888,6 +889,7 @@ struct addr_list {
struct tftp_prefix {
char *interface;
char *prefix;
+ int missing;
struct tftp_prefix *next;
};
diff --git a/src/option.c b/src/option.c
index 209fa69..fa5e4d3 100644
--- a/src/option.c
+++ b/src/option.c
@@ -147,6 +147,7 @@ struct myoption {
#define LOPT_LOCAL_SERVICE 335
#define LOPT_DNSSEC_TIME 336
#define LOPT_LOOP_DETECT 337
+#define LOPT_TFTP_NO_FAIL 338
#ifdef HAVE_GETOPT_LONG
static const struct option opts[] =
@@ -227,6 +228,7 @@ static const struct myoption opts[] =
{ "dhcp-ignore-names", 2, 0, LOPT_NO_NAMES },
{ "enable-tftp", 2, 0, LOPT_TFTP },
{ "tftp-secure", 0, 0, LOPT_SECURE },
+ { "tftp-no-fail", 0, 0, LOPT_TFTP_NO_FAIL },
{ "tftp-unique-root", 0, 0, LOPT_APREF },
{ "tftp-root", 1, 0, LOPT_PREFIX },
{ "tftp-max", 1, 0, LOPT_TFTP_MAX },
@@ -402,6 +404,7 @@ static struct {
{ LOPT_PREFIX, ARG_DUP, "<dir>[,<iface>]", gettext_noop("Export files by TFTP only from the specified subtree."), NULL },
{ LOPT_APREF, OPT_TFTP_APREF, NULL, gettext_noop("Add client IP address to tftp-root."), NULL },
{ LOPT_SECURE, OPT_TFTP_SECURE, NULL, gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL },
+ { LOPT_TFTP_NO_FAIL, OPT_TFTP_NO_FAIL, NULL, gettext_noop("Do not terminate the service if TFTP directories are inaccessible."), NULL },
{ LOPT_TFTP_MAX, ARG_ONE, "<integer>", gettext_noop("Maximum number of conncurrent TFTP transfers (defaults to %s)."), "#" },
{ LOPT_NOBLOCK, OPT_TFTP_NOBLOCK, NULL, gettext_noop("Disable the TFTP blocksize extension."), NULL },
{ LOPT_TFTP_LC, OPT_TFTP_LC, NULL, gettext_noop("Convert TFTP filenames to lowercase"), NULL },
--
2.1.4