Compare commits

...
12 Commits
14 changed files with 234 additions and 52 deletions

No files matched your search

+1
View File
@@ -2,6 +2,7 @@ src/*.o
src/*.mo
src/dnsmasq.pot
src/dnsmasq
src/dnsmasq_baseline
src/.configured
contrib/wrt/dhcp_lease_time
contrib/wrt/dhcp_release
+12 -1
View File
@@ -101,7 +101,18 @@ version 2.67
(provide TFTP to the same interfaces we provide DHCP to)
is retained. Thanks to Lonnie Abelbeck for the suggestion.
Add --dhcp-relay config option.
Add --dhcp-relay config option. Many thanks to vtsl.net
for sponsoring this development.
Fix crash with empty tag: in --dhcp-range. Thanks to
Kaspar Schleiser for the bug report.
Add "baseline" and "bloatcheck" makefile targets, for
revealing size changes during development. Thanks to
Vladislav Grishenko for the patch.
Cope with DHCPv6 clients which send REQUESTs without
address options - treat them as SOLICIT with rapid commit.
version 2.66
+19 -6
View File
@@ -77,10 +77,14 @@ all : $(BUILDDIR)
build_libs="$(dbus_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs)" \
-f $(top)/Makefile dnsmasq
clean :
rm -f *~ $(BUILDDIR)/*.mo contrib/*/*~ */*~ $(BUILDDIR)/*.pot
mostly_clean :
rm -f $(BUILDDIR)/*.mo $(BUILDDIR)/*.pot
rm -f $(BUILDDIR)/.configured $(BUILDDIR)/*.o $(BUILDDIR)/dnsmasq.a $(BUILDDIR)/dnsmasq
rm -rf core */core
clean : mostly_clean
rm -f $(BUILDDIR)/dnsmasq_baseline
rm -f core */core
rm -f *~ contrib/*/*~ */*~
install : all install-common
@@ -113,6 +117,16 @@ merge :
$(BUILDDIR):
mkdir -p $(BUILDDIR)
# rules below are helpers for size tracking
baseline : mostly_clean all
@cd $(BUILDDIR) && \
mv dnsmasq dnsmasq_baseline
bloatcheck : $(BUILDDIR)/dnsmasq_baseline mostly_clean all
@cd $(BUILDDIR) && \
$(top)/bld/bloat-o-meter dnsmasq_baseline dnsmasq; \
size dnsmasq_baseline dnsmasq
# rules below are targets in recusive makes with cwd=$(BUILDDIR)
@@ -126,7 +140,7 @@ $(objs:.o=.c) $(hdrs):
.c.o:
$(CC) $(CFLAGS) $(COPTS) $(i18n) $(build_cflags) $(RPM_OPT_FLAGS) -c $<
dnsmasq : .configured $(hdrs) $(objs)
dnsmasq : .configured $(hdrs) $(objs)
$(CC) $(LDFLAGS) -o $@ $(objs) $(build_libs) $(LIBS)
dnsmasq.pot : $(objs:.o=.c) $(hdrs)
@@ -135,5 +149,4 @@ dnsmasq.pot : $(objs:.o=.c) $(hdrs)
%.mo : $(top)/$(PO)/%.po dnsmasq.pot
$(MSGMERGE) -o - $(top)/$(PO)/$*.po dnsmasq.pot | $(MSGFMT) -o $*.mo -
.PHONY : all clean install install-common all-i18n install-i18n merge
.PHONY : all clean mostly_clean install install-common all-i18n install-i18n merge baseline bloatcheck
+130
View File
@@ -0,0 +1,130 @@
#!/usr/bin/env python
#
# Copyright 2004 Matt Mackall <mpm@selenic.com>
#
# Inspired by perl Bloat-O-Meter (c) 1997 by Andi Kleen
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
import sys, os#, re
def usage():
sys.stderr.write("usage: %s [-t] file1 file2\n" % sys.argv[0])
sys.exit(-1)
f1, f2 = (None, None)
flag_timing, dashes = (False, False)
for f in sys.argv[1:]:
if f.startswith("-"):
if f == "--": # sym_args
dashes = True
break
if f == "-t": # timings
flag_timing = True
else:
if not os.path.exists(f):
sys.stderr.write("Error: file '%s' does not exist\n" % f)
usage()
if f1 is None:
f1 = f
elif f2 is None:
f2 = f
if flag_timing:
import time
if f1 is None or f2 is None:
usage()
sym_args = " ".join(sys.argv[3 + flag_timing + dashes:])
def getsizes(file):
sym, alias, lut = {}, {}, {}
for l in os.popen("readelf -W -s %s %s" % (sym_args, file)).readlines():
l = l.strip()
if not (len(l) and l[0].isdigit() and len(l.split()) == 8):
continue
num, value, size, typ, bind, vis, ndx, name = l.split()
if ndx == "UND": continue # skip undefined
if typ in ["SECTION", "FILES"]: continue # skip sections and files
if "." in name: name = "static." + name.split(".")[0]
value = int(value, 16)
size = int(size, 16) if size.startswith('0x') else int(size)
if vis != "DEFAULT" and bind != "GLOBAL": # see if it is an alias
alias[(value, size)] = {"name" : name}
else:
sym[name] = {"addr" : value, "size": size}
lut[(value, size)] = 0
for addr, sz in iter(alias.keys()):
# If the non-GLOBAL sym has an implementation elsewhere then
# it's an alias, disregard it.
if not (addr, sz) in lut:
# If this non-GLOBAL sym does not have an implementation at
# another address, then treat it as a normal symbol.
sym[alias[(addr, sz)]["name"]] = {"addr" : addr, "size": sz}
for l in os.popen("readelf -W -S " + file).readlines():
x = l.split()
if len(x)<6: continue
# Should take these into account too!
#if x[1] not in [".text", ".rodata", ".symtab", ".strtab"]: continue
if x[1] not in [".rodata"]: continue
sym[x[1]] = {"addr" : int(x[3], 16), "size" : int(x[5], 16)}
return sym
if flag_timing:
start_t1 = int(time.time() * 1e9)
old = getsizes(f1)
if flag_timing:
end_t1 = int(time.time() * 1e9)
start_t2 = int(time.time() * 1e9)
new = getsizes(f2)
if flag_timing:
end_t2 = int(time.time() * 1e9)
start_t3 = int(time.time() * 1e9)
grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0
delta, common = [], {}
for name in iter(old.keys()):
if name in new:
common[name] = 1
for name in old:
if name not in common:
remove += 1
sz = old[name]["size"]
down += sz
delta.append((-sz, name))
for name in new:
if name not in common:
add += 1
sz = new[name]["size"]
up += sz
delta.append((sz, name))
for name in common:
d = new[name].get("size", 0) - old[name].get("size", 0)
if d>0: grow, up = grow+1, up+d
elif d<0: shrink, down = shrink+1, down-d
else:
continue
delta.append((d, name))
delta.sort()
delta.reverse()
if flag_timing:
end_t3 = int(time.time() * 1e9)
print("%-48s %7s %7s %+7s" % ("function", "old", "new", "delta"))
for d, n in delta:
if d:
old_sz = old.get(n, {}).get("size", "-")
new_sz = new.get(n, {}).get("size", "-")
print("%-48s %7s %7s %+7d" % (n, old_sz, new_sz, d))
print("-"*78)
total="(add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s)%%sTotal: %s bytes"\
% (add, remove, grow, shrink, up, -down, up-down)
print(total % (" "*(80-len(total))))
if flag_timing:
print("\n%d/%d; %d Parse origin/new; processing nsecs" %
(end_t1-start_t1, end_t2-start_t2, end_t3-start_t3))
print("total nsecs: %d" % (end_t3-start_t1))
+1 -1
View File
@@ -12,7 +12,7 @@
# first. This favours, eg v2.63 over 2.63rc6.
if which git >/dev/null 2>&1 && [ -d $1/.git ]; then
cd $1; git describe
cd $1; git describe | sed 's/^v//'
elif grep '\$Format:%d\$' $1/VERSION >/dev/null 2>&1; then
# unsubstituted VERSION, but no git available.
echo UNKNOWN
+1
View File
@@ -1,6 +1,7 @@
dnsmasq (2.67-1) unstable; urgency=low
* New upstream.
* Update resolvconf script. (closes: #720732)
-- Simon Kelley <simon@thekelleys.org.uk> Wed, 4 Aug 2013 14:53:22 +0000
+1 -1
View File
@@ -7,7 +7,7 @@ Standards-Version: 3.9.3
Package: dnsmasq
Architecture: all
Depends: netbase, dnsmasq-base(>= ${source:Version})
Depends: netbase, dnsmasq-base(>= ${binary:Version})
Suggests: resolvconf
Conflicts: resolvconf (<<1.15)
Description: Small caching DNS proxy and DHCP/TFTP server
+3 -1
View File
@@ -64,7 +64,9 @@ Notes on configuring dnsmasq as packaged for Debian.
noi18n : omit translations and internationalisation support.
noidn : omit international domain name support, must be
combined with noi18n to be effective.
gitversion : set the version of the produced packages from the
git-derived versioning information on the source,
rather the the debian changelog.
(9) Dnsmasq comes as three packages - dnsmasq-utils, dnsmasq-base and
dnsmasq. Dnsmasq-base provides the dnsmasq executable and
+7 -8
View File
@@ -16,8 +16,7 @@ set -e
RUN_DIR="/var/run/dnsmasq"
RSLVRLIST_FILE="${RUN_DIR}/resolv.conf"
TMP_FILE="${RSLVRLIST_FILE}_new.$$"
MY_RECORD_NAME="lo.dnsmasq"
DNSCRYPT_RECORD_NAME="lo.dnscrypt"
MY_NAME_FOR_RESOLVCONF="dnsmasq"
[ -x /usr/sbin/dnsmasq ] || exit 0
[ -x /lib/resolvconf/list-records ] || exit 1
@@ -46,14 +45,14 @@ if [ ! -d "$RUN_DIR" ] && ! mkdir --parents --mode=0755 "$RUN_DIR" ; then
fi
RSLVCNFFILES=""
for F in $(/lib/resolvconf/list-records --after "$MY_RECORD_NAME") ; do
for F in $(/lib/resolvconf/list-records --after "lo.$MY_NAME_FOR_RESOLVCONF") ; do
case "$F" in
"$MY_RECORD_NAME")
# Omit
"lo.$MY_NAME_FOR_RESOLVCONF")
# Omit own record
;;
"$DNSCRYPT_RECORD_NAME")
# Dnscrypt, I only have eyes for you
RSLVCNFFILES="$DNSCRYPT_RECORD_NAME"
lo.*)
# Include no more records after one for a local nameserver
RSLVCNFFILES="${RSLVCNFFILES:+$RSLVCNFFILES }$F"
break
;;
*)
+9 -4
View File
@@ -23,6 +23,11 @@ TARGET = install-i18n
DEB_BUILD_ARCH_OS := $(shell dpkg-architecture -qDEB_BUILD_ARCH_OS)
# Force package version based on git tags.
ifneq (,$(filter gitversion,$(DEB_BUILD_OPTIONS)))
PACKAGE_VERSION = $(shell bld/get-version `pwd` | sed 's/[a-z]/~&/; s/-/./g; s/$$/-1/; s/^/-v/';)
endif
ifeq (,$(filter nodbus,$(DEB_BUILD_OPTIONS)))
COPTS += -DHAVE_DBUS
endif
@@ -103,7 +108,7 @@ binary-indep: checkroot
install -m 644 debian/insserv debian/daemon/etc/insserv.conf.d/dnsmasq
ln -s $(package) debian/daemon/usr/share/doc/dnsmasq
cd debian/daemon && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | xargs -r0 md5sum > DEBIAN/md5sums
dpkg-gencontrol -pdnsmasq -Pdebian/daemon
dpkg-gencontrol $(PACKAGE_VERSION) -T -pdnsmasq -Pdebian/daemon
chown -R root.root debian/daemon
chmod -R g-ws debian/daemon
dpkg --build debian/daemon ..
@@ -150,8 +155,8 @@ ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
strip -R .note -R .comment debian/base/usr/sbin/dnsmasq
endif
cd debian/base && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | xargs -r0 md5sum > DEBIAN/md5sums
dpkg-shlibdeps debian/base/usr/sbin/dnsmasq
dpkg-gencontrol -pdnsmasq-base -Pdebian/base
dpkg-shlibdeps --warnings=1 debian/base/usr/sbin/dnsmasq
dpkg-gencontrol $(PACKAGE_VERSION) -pdnsmasq-base -Pdebian/base
chown -R root.root debian/base
chmod -R g-ws debian/base
dpkg --build debian/base ..
@@ -178,7 +183,7 @@ ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
endif
cd debian/utils && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | xargs -r0 md5sum > DEBIAN/md5sums
dpkg-shlibdeps -Tdebian/utils-substvars debian/utils/usr/bin/dhcp_release debian/utils/usr/bin/dhcp_lease_time
dpkg-gencontrol -Tdebian/utils-substvars -pdnsmasq-utils -Pdebian/utils
dpkg-gencontrol $(PACKAGE_VERSION) -Tdebian/utils-substvars -pdnsmasq-utils -Pdebian/utils
chown -R root.root debian/utils
chmod -R g-ws debian/utils
dpkg --build debian/utils ..
+4 -3
View File
@@ -237,16 +237,17 @@ int main (int argc, char **argv)
#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP)
/* after enumerate_interfaces() */
if (daemon->dhcp || daemon->relay4)
if (daemon->dhcp)
{
bindtodevice(daemon->dhcpfd);
if (!daemon->relay4)
bindtodevice(daemon->dhcpfd);
if (daemon->enable_pxe)
bindtodevice(daemon->pxefd);
}
#endif
#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP6)
if (daemon->doing_dhcp6 || daemon->relay6)
if (daemon->doing_dhcp6 && !daemon->relay6)
bindtodevice(daemon->dhcp6fd);
#endif
}
+8 -4
View File
@@ -443,7 +443,7 @@ static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
int enumerate_interfaces(int reset)
{
static struct addrlist *spare = NULL;
static int done = 0;
static int done = 0, active = 0;
struct iface_param param;
int errsave, ret = 1;
struct addrlist *addr, *tmp;
@@ -451,18 +451,21 @@ int enumerate_interfaces(int reset)
/* Do this max once per select cycle - also inhibits netlink socket use
in TCP child processes. */
if (reset)
{
done = 0;
return 1;
}
if (done)
if (done || active)
return 1;
done = 1;
/* protect against recusive calls from iface_enumerate(); */
active = 1;
if ((param.fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
return 0;
@@ -504,7 +507,8 @@ int enumerate_interfaces(int reset)
errno = errsave;
spare = param.spare;
active = 0;
return ret;
}
+3 -1
View File
@@ -2337,7 +2337,9 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
struct dhcp_netid *tt = opt_malloc(sizeof (struct dhcp_netid));
tt->net = opt_string_alloc(arg+4);
tt->next = new->filter;
new->filter = tt;
/* ignore empty tag */
if (tt->net)
new->filter = tt;
}
else
{
+35 -22
View File
@@ -21,7 +21,7 @@
struct state {
unsigned char *clid;
int clid_len, iaid, ia_type, interface, hostname_auth;
int clid_len, iaid, ia_type, interface, hostname_auth, lease_allocate;
char *client_hostname, *hostname, *domain, *send_domain;
struct dhcp_context *context;
struct in6_addr *link_address;
@@ -55,7 +55,7 @@ static void mark_context_used(struct state *state, struct dhcp_context *context,
static void mark_config_used(struct dhcp_context *context, struct in6_addr *addr);
static int check_address(struct state *state, struct in6_addr *addr);
static void add_address(struct state *state, struct dhcp_context *context, unsigned int lease_time, void *ia_option,
unsigned int *min_time, struct in6_addr *addr, int update_lease, time_t now);
unsigned int *min_time, struct in6_addr *addr, time_t now);
static void update_leases(struct state *state, struct dhcp_context *context, struct in6_addr *addr, unsigned int lease_time, time_t now);
static int add_local_addrs(struct dhcp_context *context);
static struct dhcp_netid *add_options(struct state *state, struct in6_addr *fallback, struct dhcp_context *context, int do_refresh);
@@ -226,6 +226,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
state.end = inbuff + sz;
state.clid = NULL;
state.clid_len = 0;
state.lease_allocate = 0;
state.context_tags = NULL;
state.tags = tags;
state.link_address = link_address;
@@ -536,27 +537,29 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
{
default:
return 0;
case DHCP6SOLICIT:
{
void *rapid_commit = opt6_find(state.packet_options, state.end, OPTION6_RAPID_COMMIT, 0);
int address_assigned = 0;
/* tags without all prefix-class tags */
struct dhcp_netid *solicit_tags = tagif;
struct dhcp_context *c;
if (rapid_commit)
*outmsgtypep = DHCP6ADVERTISE;
if (opt6_find(state.packet_options, state.end, OPTION6_RAPID_COMMIT, 0))
{
*outmsgtypep = DHCP6REPLY;
state.lease_allocate = 1;
o = new_opt6(OPTION6_RAPID_COMMIT);
end_opt6(o);
}
/* set reply message type */
*outmsgtypep = rapid_commit ? DHCP6REPLY : DHCP6ADVERTISE;
log6_packet(&state, "DHCPSOLICIT", NULL, ignore ? _("ignored") : NULL);
log6_packet(&state, "DHCPSOLICIT", NULL, ignore ? _("ignored") : NULL);
request_no_address:
if (ignore)
return 0;
@@ -671,7 +674,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
if (dump_all_prefix_classes && state.ia_type == OPTION6_IA_NA)
state.send_prefix_class = prefix_class_from_context(c);
#endif
add_address(&state, c, lease_time, ia_option, &min_time, req_addr, rapid_commit != NULL, now);
add_address(&state, c, lease_time, ia_option, &min_time, req_addr, now);
mark_context_used(&state, context, req_addr);
get_context_tag(&state, c);
address_assigned = 1;
@@ -695,7 +698,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
if (dump_all_prefix_classes && state.ia_type == OPTION6_IA_NA)
state.send_prefix_class = prefix_class_from_context(c);
#endif
add_address(&state, c, lease_time, NULL, &min_time, &addr, rapid_commit != NULL, now);
add_address(&state, c, lease_time, NULL, &min_time, &addr, now);
mark_context_used(&state, context, &addr);
get_context_tag(&state, c);
address_assigned = 1;
@@ -712,7 +715,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
if (dump_all_prefix_classes && state.ia_type == OPTION6_IA_NA)
state.send_prefix_class = prefix_class_from_context(c);
#endif
add_address(&state, c, c->lease_time, NULL, &min_time, req_addr, rapid_commit != NULL, now);
add_address(&state, c, c->lease_time, NULL, &min_time, req_addr, now);
mark_context_used(&state, context, req_addr);
get_context_tag(&state, c);
address_assigned = 1;
@@ -726,7 +729,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
if (dump_all_prefix_classes && state.ia_type == OPTION6_IA_NA)
state.send_prefix_class = prefix_class_from_context(c);
#endif
add_address(&state, c, c->lease_time, NULL, &min_time, &addr, rapid_commit != NULL, now);
add_address(&state, c, c->lease_time, NULL, &min_time, &addr, now);
mark_context_used(&state, context, &addr);
get_context_tag(&state, c);
address_assigned = 1;
@@ -766,9 +769,11 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
case DHCP6REQUEST:
{
int address_assigned = 0;
int start = save_counter(-1);
/* set reply message type */
*outmsgtypep = DHCP6REPLY;
state.lease_allocate = 1;
log6_packet(&state, "DHCPREQUEST", NULL, ignore ? _("ignored") : NULL);
@@ -783,7 +788,15 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
if (!check_ia(&state, opt, &ia_end, &ia_option))
continue;
if (!ia_option)
{
/* If we get a request with a IA_*A without addresses, treat it exactly like
a SOLICT with rapid commit set. */
save_counter(start);
goto request_no_address;
}
o = build_ia(&state, &t1cntr);
for (; ia_option; ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
@@ -829,7 +842,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
if (dump_all_prefix_classes && state.ia_type == OPTION6_IA_NA)
state.send_prefix_class = prefix_class_from_context(c);
#endif
add_address(&state, dynamic, lease_time, ia_option, &min_time, req_addr, 1, now);
add_address(&state, dynamic, lease_time, ia_option, &min_time, req_addr, now);
get_context_tag(&state, dynamic);
address_assigned = 1;
}
@@ -1505,7 +1518,7 @@ static void end_ia(int t1cntr, unsigned int min_time, int do_fuzz)
}
static void add_address(struct state *state, struct dhcp_context *context, unsigned int lease_time, void *ia_option,
unsigned int *min_time, struct in6_addr *addr, int do_update, time_t now)
unsigned int *min_time, struct in6_addr *addr, time_t now)
{
unsigned int valid_time = 0, preferred_time = 0;
int o = new_opt6(OPTION6_IAADDR);
@@ -1535,7 +1548,7 @@ static void add_address(struct state *state, struct dhcp_context *context, unsig
end_opt6(o);
if (do_update)
if (state->lease_allocate)
update_leases(state, context, addr, valid_time, now);
if ((lease = lease6_find_by_addr(addr, 128, 0)))
@@ -1559,7 +1572,7 @@ static void add_address(struct state *state, struct dhcp_context *context, unsig
}
}
log6_packet(state, do_update ? "DHCPREPLY" : "DHCPADVERTISE", addr, state->hostname);
log6_packet(state, state->lease_allocate ? "DHCPREPLY" : "DHCPADVERTISE", addr, state->hostname);
}