import of dnsmasq-2.25.tar.gz

This commit is contained in:
Simon Kelley
2006-01-14 20:33:46 +00:00
parent b8187c80a8
commit e17fb629a2
19 changed files with 2171 additions and 354 deletions

View File

@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2005 Simon Kelley
/* dnsmasq is Copyright (c) 2000-2006 Simon Kelley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -12,7 +12,7 @@
/* Author's email: simon@thekelleys.org.uk */
#define VERSION "2.24"
#define VERSION "2.25"
#define FTABSIZ 150 /* max number of outstanding requests */
#define MAX_PROCS 20 /* max no children for TCP requests */
@@ -78,26 +78,6 @@
# define T_OPT 41
#endif
/* Decide if we're going to support IPv6 */
/* We assume that systems which don't have IPv6
headers don't have ntop and pton either */
#if defined(INET6_ADDRSTRLEN) && defined(IPV6_V6ONLY) && !defined(NO_IPV6)
# define HAVE_IPV6
# define ADDRSTRLEN INET6_ADDRSTRLEN
# if defined(SOL_IPV6)
# define IPV6_LEVEL SOL_IPV6
# else
# define IPV6_LEVEL IPPROTO_IPV6
# endif
#elif defined(INET_ADDRSTRLEN)
# undef HAVE_IPV6
# define ADDRSTRLEN INET_ADDRSTRLEN
#else
# undef HAVE_IPV6
# define ADDRSTRLEN 16 /* 4*3 + 3 dots + NULL */
#endif
/* Get linux C library versions. */
#if defined(__linux__) && !defined(__UCLIBC__) && !defined(__uClinux__)
# include <libio.h>
@@ -205,18 +185,17 @@ NOTES:
/* platform independent options. */
#undef HAVE_BROKEN_RTC
#define HAVE_ISC_READER
#undef HAVE_DBUS
#if defined(HAVE_BROKEN_RTC) && defined(HAVE_ISC_READER)
# error HAVE_ISC_READER is not compatible with HAVE_BROKEN_RTC
#endif
#undef HAVE_DBUS
/* platform dependent options. */
/* Must preceed __linux__ since uClinux defines __linux__ too. */
#if defined(__uClinux__) || defined(__UCLIBC__)
#undef HAVE_LINUX_IPV6_PROC
#if defined(__uClinux__)
#define HAVE_LINUX_IPV6_PROC
#define HAVE_GETOPT_LONG
#define HAVE_RTNETLINK
#undef HAVE_ARC4RANDOM
@@ -225,12 +204,32 @@ NOTES:
#define HAVE_DEV_RANDOM
#undef HAVE_SOCKADDR_SA_LEN
#undef HAVE_PSELECT
#if defined(__uClinux__)
/* Never use fork() on uClinux. Note that this is subtly different from the
--keep-in-foreground option, since it also suppresses forking new
processes for TCP connections. It's intended for use on MMU-less kernels. */
#define NO_FORK
#elif defined(__UCLIBC__)
#define HAVE_LINUX_IPV6_PROC
#if defined(__UCLIBC_HAS_GNU_GETOPT__) || \
((__UCLIBC_MAJOR__==0) && (__UCLIBC_MINOR__==9) && (__UCLIBC_SUBLEVEL__<21))
# define HAVE_GETOPT_LONG
# else
# undef HAVE_GETOPT_LONG
# endif
#define HAVE_RTNETLINK
#undef HAVE_ARC4RANDOM
#define HAVE_RANDOM
#define HAVE_DEV_URANDOM
#define HAVE_DEV_RANDOM
#undef HAVE_SOCKADDR_SA_LEN
#undef HAVE_PSELECT
#if !defined(__ARCH_HAS_MMU__)
# define NO_FORK
#endif
#if !defined(__UCLIBC_HAS_IPV6__)
# define NO_IPV6
#endif
/* libc5 - must precede __linux__ too */
/* Note to build a libc5 binary on a modern Debian system:
@@ -271,10 +270,8 @@ typedef size_t socklen_t;
#if defined(__GLIBC__) && (__GLIBC__ == 2) && \
defined(__GLIBC_MINOR__) && (__GLIBC_MINOR__ < 2)
typedef unsigned long in_addr_t;
#if defined(HAVE_IPV6)
# define HAVE_BROKEN_SOCKADDR_IN6
#endif
#endif
#elif defined(__FreeBSD__) || defined(__OpenBSD__)
#undef HAVE_LINUX_IPV6_PROC
@@ -334,5 +331,25 @@ typedef unsigned long in_addr_t;
#endif
/* Decide if we're going to support IPv6 */
/* We assume that systems which don't have IPv6
headers don't have ntop and pton either */
#if defined(INET6_ADDRSTRLEN) && defined(IPV6_V6ONLY) && !defined(NO_IPV6)
# define HAVE_IPV6
# define ADDRSTRLEN INET6_ADDRSTRLEN
# if defined(SOL_IPV6)
# define IPV6_LEVEL SOL_IPV6
# else
# define IPV6_LEVEL IPPROTO_IPV6
# endif
#elif defined(INET_ADDRSTRLEN)
# undef HAVE_IPV6
# define ADDRSTRLEN INET_ADDRSTRLEN
#else
# undef HAVE_IPV6
# define ADDRSTRLEN 16 /* 4*3 + 3 dots + NULL */
#endif

View File

@@ -224,7 +224,17 @@ void dhcp_packet(struct daemon *daemon, time_t now)
#endif
{
struct in_addr iface_netmask, iface_broadcast;
#ifdef HAVE_RTNETLINK
static int warned = 0;
if (!warned)
{
syslog(LOG_WARNING, _("Cannot use RTnetlink socket, falling back to ioctl API"));
warned = 1;
}
#endif
if (ioctl(daemon->dhcpfd, SIOCGIFNETMASK, &ifr) < 0)
return;
iface_netmask = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
@@ -447,24 +457,29 @@ struct dhcp_context *address_available(struct dhcp_context *context, struct in_a
struct dhcp_context *narrow_context(struct dhcp_context *context, struct in_addr taddr)
{
/* We start of with a set of possible contexts, all on the current subnet.
/* We start of with a set of possible contexts, all on the current physical interface.
These are chained on ->current.
Here we have an address, and return the actual context correponding to that
address. Note that none may fit, if the address came a dhcp-host and is outside
any dhcp-range. In that case we return a static range is possible, or failing that,
any context on the subnet. (If there's more than one, this is a dodgy configuration:
maybe there should be a warning.) */
any dhcp-range. In that case we return a static range if possible, or failing that,
any context on the correct subnet. (If there's more than one, this is a dodgy
configuration: maybe there should be a warning.) */
struct dhcp_context *tmp = address_available(context, taddr);
struct dhcp_context *tmp;
if (tmp)
if ((tmp = address_available(context, taddr)))
return tmp;
for (tmp = context; tmp; tmp = tmp->current)
if (tmp->flags & CONTEXT_STATIC)
if (is_same_net(taddr, tmp->start, tmp->netmask) &&
(tmp->flags & CONTEXT_STATIC))
return tmp;
return context;
for (tmp = context; tmp; tmp = tmp->current)
if (is_same_net(taddr, tmp->start, tmp->netmask))
return tmp;
return NULL;
}
struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct in_addr addr)

View File

@@ -26,6 +26,9 @@ static char *compile_opts =
#ifdef HAVE_BROKEN_RTC
"no-RTC "
#endif
#ifdef HAVE_RTNETLINK
"RTNetlink "
#endif
#ifndef HAVE_ISC_READER
"no-"
#endif
@@ -37,7 +40,7 @@ static char *compile_opts =
#ifdef NO_GETTEXT
"no-"
#endif
"i18n";
"I18N ";
static volatile int sigterm, sighup, sigusr1, sigalarm, num_kids, in_child;

View File

@@ -12,7 +12,7 @@
/* Author's email: simon@thekelleys.org.uk */
#define COPYRIGHT "Copyright (C) 2000-2005 Simon Kelley"
#define COPYRIGHT "Copyright (C) 2000-2006 Simon Kelley"
#ifdef __linux__
/* for pselect.... */

View File

@@ -1049,11 +1049,15 @@ int answer_request(HEADER *header, char *limit, unsigned int qlen, struct daemon
if (t->class == qclass && hostname_isequal(name, t->name))
{
ans = 1;
log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, 0, NULL, 0);
if (!dryrun &&
add_resource_record(header, limit, &trunc, nameoffset, &ansp, 0, NULL,
T_TXT, t->class, "t", t->len, t->txt))
anscount++;
if (!dryrun)
{
log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, 0, NULL, 0);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->local_ttl, NULL,
T_TXT, t->class, "t", t->len, t->txt))
anscount++;
}
}
}
}

View File

@@ -275,19 +275,31 @@ int dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *iface_
message = _("no address configured");
else
{
if ((lease = lease_find_by_client(mess->chaddr, NULL, 0)))
if (!(lease = lease_find_by_client(mess->chaddr, NULL, 0)) ||
!address_available(context, lease->addr))
{
if (lease)
{
/* lease exists, wrong network. */
lease_prune(lease, now);
lease = NULL;
}
if (!address_allocate(context, daemon, &mess->yiaddr, chaddr, netid, now))
message = _("no address available");
}
else
mess->yiaddr = lease->addr;
else if (!address_allocate(context, daemon, &mess->yiaddr, chaddr, netid, now))
message = _("no address available");
}
if (!message && !lease && (!(lease = lease_allocate(chaddr, NULL, 0, mess->yiaddr))))
message = _("no leases left");
if (!message && !(context = narrow_context(context, mess->yiaddr)))
message = _("wrong network");
if (!message)
{
logaddr = &mess->yiaddr;
context = narrow_context(context, mess->yiaddr);
if (context->netid.net && !(context->flags & CONTEXT_FILTER))
{
@@ -523,10 +535,9 @@ int dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *iface_
log_packet("DISCOVER", opt ? &addr : NULL, chaddr, iface_name, message);
}
if (message)
if (message || !(context = narrow_context(context, mess->yiaddr)))
return 0;
context = narrow_context(context, mess->yiaddr);
if (context->netid.net && !(context->flags & CONTEXT_FILTER))
{
context->netid.next = netid;
@@ -572,7 +583,11 @@ int dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *iface_
if ((opt = option_find(mess, sz, OPTION_SERVER_IDENTIFIER, INADDRSZ)))
{
/* SELECTING */
if (context->local.s_addr != option_addr(opt).s_addr)
for (; context; context = context->current)
if (context->local.s_addr == option_addr(opt).s_addr)
break;
if (!context)
return 0;
/* If a lease exists for this host and another address, squash it. */
@@ -608,14 +623,14 @@ int dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *iface_
}
log_packet("REQUEST", &mess->yiaddr, chaddr, iface_name, NULL);
if (!message)
{
struct dhcp_config *addr_config;
/* If a machine moves networks whilst it has a lease, we catch that here. */
if (!is_same_net(mess->yiaddr, context->start, context->netmask))
if (!(context = narrow_context(context, mess->yiaddr)))
{
/* If a machine moves networks whilst it has a lease, we catch that here. */
message = _("wrong network");
/* ensure we broadcast NAK */
unicast_dest = 0;
@@ -625,7 +640,7 @@ int dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *iface_
else if (!address_available(context, mess->yiaddr) &&
(!have_config(config, CONFIG_ADDR) || config->addr.s_addr != mess->yiaddr.s_addr))
message = _("address not available");
/* Check if a new static address has been configured. Be very sure that
when the client does DISCOVER, it will get the static address, otherwise
an endless protocol loop will ensue. */
@@ -674,7 +689,6 @@ int dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *iface_
log_packet("ACK", &mess->yiaddr, chaddr, iface_name, hostname);
context = narrow_context(context, mess->yiaddr);
if (context->netid.net && !(context->flags & CONTEXT_FILTER))
{
context->netid.next = netid;
@@ -719,10 +733,10 @@ int dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *iface_
log_packet("INFORM", &mess->ciaddr, chaddr, iface_name, message);
if (message || mess->ciaddr.s_addr == 0)
if (message || mess->ciaddr.s_addr == 0 ||
!(context = narrow_context(context, mess->ciaddr)))
return 0;
context = narrow_context(context, mess->ciaddr);
if (context->netid.net)
{
context->netid.next = netid;