From bec366b4041df72b559e713f1c924177676e6eb0 Mon Sep 17 00:00:00 2001 From: Simon Kelley Date: Wed, 24 Feb 2016 22:03:26 +0000 Subject: [PATCH] Add --tftp-mtu option. --- CHANGELOG | 4 ++++ man/dnsmasq.8 | 4 ++++ src/dnsmasq.h | 2 +- src/option.c | 10 +++++++++- src/tftp.c | 14 ++++++++++++-- 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 6d9ba49..9218b8c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -53,6 +53,10 @@ version 2.76 Add --dhcp-ttl option. + Add --tftp-mtu option. Thanks to Patrick McLean for the + initial patch. + + version 2.75 Fix reversion on 2.74 which caused 100% CPU use when a dhcp-script is configured. Thanks to Adrian Davey for diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 index 2bcce20..3cf48cd 100644 --- a/man/dnsmasq.8 +++ b/man/dnsmasq.8 @@ -1810,6 +1810,10 @@ require about (2*n) + 10 descriptors. If .B --tftp-port-range is given, that can affect the number of concurrent connections. .TP +.B --tftp-mtu= +Use size as the ceiling of the MTU supported by the intervening network when +negotiating TFTP blocksize, overriding the MTU setting of the local interface if it is larger. +.TP .B --tftp-no-blocksize Stop the TFTP server from negotiating the "blocksize" option with a client. Some buggy clients request this option but then behave badly diff --git a/src/dnsmasq.h b/src/dnsmasq.h index 9f73c3b..280ad9d 100644 --- a/src/dnsmasq.h +++ b/src/dnsmasq.h @@ -975,7 +975,7 @@ extern struct daemon { struct dhcp_netid_list *dhcp_ignore, *dhcp_ignore_names, *dhcp_gen_names; struct dhcp_netid_list *force_broadcast, *bootp_dynamic; struct hostsfile *dhcp_hosts_file, *dhcp_opts_file, *dynamic_dirs; - int dhcp_max, tftp_max; + int dhcp_max, tftp_max, tftp_mtu; int dhcp_server_port, dhcp_client_port; int start_tftp_port, end_tftp_port; unsigned int min_leasetime; diff --git a/src/option.c b/src/option.c index 3f6d162..765965f 100644 --- a/src/option.c +++ b/src/option.c @@ -158,7 +158,8 @@ struct myoption { #define LOPT_CPE_ID 346 #define LOPT_SCRIPT_ARP 347 #define LOPT_DHCPTTL 348 - +#define LOPT_TFTP_MTU 349 + #ifdef HAVE_GETOPT_LONG static const struct option opts[] = #else @@ -244,6 +245,7 @@ static const struct myoption opts[] = { "tftp-unique-root", 0, 0, LOPT_APREF }, { "tftp-root", 1, 0, LOPT_PREFIX }, { "tftp-max", 1, 0, LOPT_TFTP_MAX }, + { "tftp-mtu", 1, 0, LOPT_TFTP_MTU }, { "tftp-lowercase", 0, 0, LOPT_TFTP_LC }, { "ptr-record", 1, 0, LOPT_PTR }, { "naptr-record", 1, 0, LOPT_NAPTR }, @@ -432,6 +434,7 @@ static struct { { 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, "", gettext_noop("Maximum number of conncurrent TFTP transfers (defaults to %s)."), "#" }, + { LOPT_TFTP_MTU, ARG_ONE, "", gettext_noop("Maximum MTU to use for TFTP transfers."), NULL }, { 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 }, { LOPT_TFTPPORTS, ARG_ONE, ",", gettext_noop("Ephemeral port range for use by TFTP transfers."), NULL }, @@ -2625,6 +2628,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma ret_err(gen_err); break; + case LOPT_TFTP_MTU: /* --tftp-mtu */ + if (!atoi_check(arg, &daemon->tftp_mtu)) + ret_err(gen_err); + break; + case LOPT_PREFIX: /* --tftp-prefix */ comma = split(arg); if (comma) diff --git a/src/tftp.c b/src/tftp.c index 00ed2fc..dc4aa85 100644 --- a/src/tftp.c +++ b/src/tftp.c @@ -103,8 +103,10 @@ void tftp_request(struct listener *listen, time_t now) if (listen->iface) { addr = listen->iface->addr; - mtu = listen->iface->mtu; name = listen->iface->name; + mtu = listen->iface->mtu; + if (daemon->tftp_mtu != 0 && daemon->tftp_mtu < mtu) + mtu = daemon->tftp_mtu; } else { @@ -234,9 +236,17 @@ void tftp_request(struct listener *listen, time_t now) strncpy(ifr.ifr_name, name, IF_NAMESIZE); if (ioctl(listen->tftpfd, SIOCGIFMTU, &ifr) != -1) - mtu = ifr.ifr_mtu; + { + mtu = ifr.ifr_mtu; + if (daemon->tftp_mtu != 0 && daemon->tftp_mtu < mtu) + mtu = daemon->tftp_mtu; + } } + /* Failed to get interface mtu - can use configured value. */ + if (mtu == 0) + mtu = daemon->tftp_mtu; + if (name) { /* check for per-interface prefix */