Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
D
Dnsmasq
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
Dnsmasq
Commits
de37951c
Commit
de37951c
authored
Jun 22, 2004
by
Simon Kelley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
import of dnsmasq-2.9.tar.gz
parent
a222641c
Changes
15
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
467 additions
and
232 deletions
+467
-232
CHANGELOG
CHANGELOG
+53
-0
FAQ
FAQ
+51
-4
dnsmasq-rh.spec
dnsmasq-rh.spec
+1
-1
dnsmasq-suse.spec
dnsmasq-suse.spec
+1
-1
dnsmasq.8
dnsmasq.8
+10
-4
doc.html
doc.html
+4
-3
src/cache.c
src/cache.c
+11
-10
src/config.h
src/config.h
+1
-12
src/dhcp.c
src/dhcp.c
+4
-8
src/dnsmasq.c
src/dnsmasq.c
+65
-32
src/dnsmasq.h
src/dnsmasq.h
+13
-6
src/forward.c
src/forward.c
+132
-107
src/network.c
src/network.c
+54
-30
src/option.c
src/option.c
+59
-11
src/rfc1035.c
src/rfc1035.c
+8
-3
No files found.
CHANGELOG
View file @
de37951c
...
...
@@ -1003,3 +1003,56 @@ release 2.8
existing hostname, don't wipe it out.
Tweaked option parsing to flag some parameter errors.
release 2.9
Fixed interface filter code for two effects: 1) Fixed bug
where queries sent via loopback interface
but to the address of another interface were ignored
unless the loopback interface was explicitly configured.
2) on OpenBSD failure to configure one interface now
causes a fatal error on startup rather than an huge
stream of log messages. Thanks to Erik Jan Tromp for
finding that bug.
Changed server selection strategy to improve performance
when there are many available servers and some are
broken. The new algorithm is to pick as before for the
first try, but if a query is retried, to send to all
available servers in parallel. The first one to reply
then becomes prefered for the next query. This should
improve reliability without generating significant extra
upstream load.
Fixed breakage of special servers/addresses for
unqualified domains introduced in version 2.8
Allow fallback to "bind-interfaces" at runtime: Some
verions of *BSD seem to have enough stuff in the header
files to build but no kernel support. Also now log if
"bind-interfaces" is forced on.
Log replies from upstream servers which refuse to do
recursion - dnsmasq is not a recursive nameserver and
relies on upstream servers to do the recursion, this
flags a configuration error.
Disable client-id matching for hosts whose MAC address is
read from /etc/ethers. Patch from Oleg I. Vdovikin.
Extended --mx-host flag to allow arbitrary targets for MX
records, suggested by Moritz Bunkus.
Fixed build under NetBSD 2.0 - thanks to Felix Deichmann
for the patch.
Deal correctly with repeated addresses in /etc/hosts. The
first name found is now returned for reverse lookups,
rather than all of them.
Add back fatal errors when nonexistant
interfaces or interface addresses are given but only in
"bind-interfaces" mode. Principle of least surprise applies.
Allow # as the argument to --domain, meaning "read the
domain from the first search directive in
/etc.resolv.conf". Feature suggested by Evan Jones.
FAQ
View file @
de37951c
...
...
@@ -206,19 +206,66 @@ A: What is happening is this: The boot process sends a DHCP
the MAC address has a static allocation, that address is still in
use by the first incarnation of the machine (the one from the boot,
without a client ID.) dnsmasq therefore has to give the machine a
dynamic address from its pool. There are t
wo
ways to solve this:
dynamic address from its pool. There are t
hree
ways to solve this:
(1) persuade your DHCP client not to send a client ID, or (2) set up
the static assignment to the client ID, not the MAC address. The
default client-id will be 01:<MAC address>, so change the dhcp-host
line from "dhcp-host=11:22:33:44:55:66,1.2.3.4" to
"dhcp-host=id:01:11:22:33:44:55:66,1.2.3.4"
"dhcp-host=id:01:11:22:33:44:55:66,1.2.3.4" or (3) tell dnsmasq to
ignore client IDs for a particular MAC address, like this:
dhcp-host=11:22:33:44:55:66,id:*
Q: What network types are supported by the DHCP server?
A: Ethernet (and 802.11 wireless) are supported on all platforms. On
Linux Token Ring is also supported.
Q: What is this strange "bind-interface" option?
A: The DNS spec says that the reply to a DNS query must come from the
same address it was sent to. The traditional way to write an UDP
server to do this is to find all of the addresses belonging to the
machine (ie all the interfaces on the machine) and then create a
socket for each interface which is bound to the address of the
interface. Then when a packet is sent to address A, it is received
on the socket bound to address A and when the reply is also sent
via that socket, the source address is set to A by the kernel and
everything works. This is the how dnsmasq works when
"bind-interfaces" is set, with the obvious extension that is misses
out creating sockets for some interfaces depending on the
--interface, --address and --except-interface flags. The
disadvantage of this approach is that it breaks if interfaces don't
exist or are not configured when the daemon starts and does the
socket creation step. In a hotplug-aware world this is a real
problem.
The alternative approach is to have only one socket, which is bound
to the correct port and the wildcard IP address (0.0.0.0). That
socket will receive _all_ packets sent to port 53, no matter what
destination address they have. This solves the problem of
interfaces which are created or reconfigured after daemon
start-up. To make this work is more complicated because of the
"reply source address" problem. When a UDP packet is sent by a
socket bound to 0.0.0.0 its source address will be set to the
address of one of the machine's interfaces, but which one is not
determined and can vary depending on the OS being run. To get round
this it is neccessary to use a scary advanced API to determine the
address to which a query was sent, and force that to be the source
address in the reply. For IPv4 this stuff in non-portable and quite
often not even available (It's different between FreeBSD 5.x and
Linux, for instance, and FreeBSD 4.x, Linux 2.0.x and OpenBSD don't
have it at all.) Hence "bind-interfaces" has to always be available
as a fall back. For IPv6 the API is standard and universally
available.
It could be argued that if the --interface or --address flags are
used then binding interfaces is more appropriate, but using
wildcard binding means that dnsmasq will quite happily start up
after being told to use interfaces which don't exist, but which are
created later. Wildcard binding breaks the scenario when dnsmasq is
listening on one interface and another server (most probably BIND)
is listening on another. It's not possible for BIND to bind to an
(address,port) pair when dnsmasq has bound (wildcard,port), hence
the ability to explicitly turn off wildcard binding.
dnsmasq-rh.spec
View file @
de37951c
...
...
@@ -5,7 +5,7 @@
###############################################################################
Name: dnsmasq
Version: 2.
8
Version: 2.
9
Release: 1
Copyright: GPL
Group: System Environment/Daemons
...
...
dnsmasq-suse.spec
View file @
de37951c
...
...
@@ -5,7 +5,7 @@
###############################################################################
Name: dnsmasq
Version: 2.
8
Version: 2.
9
Release: 1
Copyright: GPL
Group: Productivity/Networking/DNS/Servers
...
...
dnsmasq.8
View file @
de37951c
...
...
@@ -120,7 +120,9 @@ option forces dnsmasq to really bind only the interfaces it is
listening on. About the only time when this is useful is when
running another nameserver on the same machine or using IP
alias. Specifying interfaces with IP alias automatically turns this
option on.
option on. Note that this only applies to the DNS part of dnsmasq, the
DHCP server always binds the wildcard address in order to receive
broadcast packets.
.TP
.B \-b, --bogus-priv
Bogus private reverse lookups. All reverse lookups for private IP ranges (ie 192.168.x.x, etc)
...
...
@@ -230,8 +232,10 @@ additional facility that /#/ matches any domain. Thus
answered from /etc/hosts or DHCP and not sent to an upstream
nameserver by a more specific --server directive.
.TP
.B \-m, --mx-host=<mx name>
Return an MX record named <mx name> pointing to the host specified in the --mx-target switch
.B \-m, --mx-host=<mx name>[,<hostname>]
Return an MX record named <mx name> pointing to the given hostname (if
given), or
the host specified in the --mx-target switch
or, if that switch is not given, the host on which dnsmasq
is running. This is useful for directing mail from systems on a LAN
to a central server.
...
...
@@ -409,7 +413,9 @@ for DHCP-configured hosts to claim. The intention is to constrain hostnames so t
.B --domain-suffix=thekelleys.org.uk
and have a machine whose DHCP hostname is "laptop". The IP address for that machine is available from
.B dnsmasq
both as "laptop" and "laptop.thekelleys.org.uk".
both as "laptop" and "laptop.thekelleys.org.uk". If the domain is
given as "#" then the domain is read from the first "search" directive
in /etc/resolv.conf (or equivalent).
.TP
.B \-E, --expand-hosts
Add the domain-suffix to simple names (without a period) in /etc/hosts
...
...
doc.html
View file @
de37951c
...
...
@@ -18,8 +18,9 @@ connected to the internet via a modem, cable-modem or ADSL
connection but would be a good choice for any small network where low
resource use and ease of configuration are important.
<P>
Dnsmasq is included in at least the following Linux distributions: Gentoo, Debian,
Smoothwall, IP-Cop, floppyfw, Firebox, Freesco and
Dnsmasq is included in at least the following Linux distributions:
Gentoo, Debian, Slackware, Suse,
Smoothwall, IP-Cop, floppyfw, Firebox, Freesco, CoyoteLinux and
Clarkconnect. It is also available as a FreeBSD port and is used in Linksys wireless routers.
<P>
Dnsmasq provides the following features:
...
...
@@ -86,7 +87,7 @@ in the .com and .net TLDs
<H2>
Download.
</H2>
Download dnsmasq
<A
HREF=
"http://www.thekelleys.org.uk/dnsmasq/"
>
here
</A>
.
<A
HREF=
"http://www.thekelleys.org.uk/dnsmasq/"
>
Download
</A>
dnsmasq here
.
The tarball includes this documentation, source, manpage and control files for building .rpms.
There are also pre-built i386 .rpms, and a
<A
HREF=
"CHANGELOG"
>
CHANGELOG
</A>
.
...
...
src/cache.c
View file @
de37951c
...
...
@@ -472,19 +472,21 @@ static void add_hosts_entry(struct crec *cache, struct all_addr *addr, int addrl
struct
crec
*
lookup
=
cache_find_by_name
(
NULL
,
cache
->
name
.
sname
,
0
,
flags
&
(
F_IPV4
|
F_IPV6
));
/* Remove duplicates in hosts files. */
if
(
lookup
&&
(
lookup
->
flags
&
F_HOSTS
)
&&
if
(
lookup
&&
(
lookup
->
flags
&
F_HOSTS
)
&&
memcmp
(
&
lookup
->
addr
,
addr
,
addrlen
)
==
0
)
free
(
cache
);
else
{
/* Ensure there is only one address -> name mapping (first one trumps) */
if
(
cache_find_by_addr
(
NULL
,
addr
,
0
,
flags
&
(
F_IPV4
|
F_IPV6
)))
flags
&=
~
F_REVERSE
;
cache
->
flags
=
flags
;
memcpy
(
&
cache
->
addr
,
addr
,
addrlen
);
cache_hash
(
cache
);
}
}
static
void
read_hostsfile
(
char
*
filename
,
int
opts
,
char
*
buff
,
char
*
domain_suffix
,
unsigned
short
addn_flag
)
static
void
read_hostsfile
(
char
*
filename
,
int
opts
,
char
*
buff
,
char
*
domain_suffix
,
int
is_addn
)
{
FILE
*
f
=
fopen
(
filename
,
"r"
);
char
*
line
;
...
...
@@ -529,6 +531,9 @@ static void read_hostsfile(char *filename, int opts, char *buff, char *domain_su
else
continue
;
if
(
is_addn
)
flags
|=
F_ADDN
;
while
((
token
=
strtok
(
NULL
,
"
\t\n\r
"
))
&&
(
*
token
!=
'#'
))
{
struct
crec
*
cache
;
...
...
@@ -543,16 +548,12 @@ static void read_hostsfile(char *filename, int opts, char *buff, char *domain_su
strcpy
(
cache
->
name
.
sname
,
token
);
strcat
(
cache
->
name
.
sname
,
"."
);
strcat
(
cache
->
name
.
sname
,
domain_suffix
);
add_hosts_entry
(
cache
,
&
addr
,
addrlen
,
flags
|
addn_flag
);
/* Only first name is cannonical and used for reverse lookups */
flags
&=
~
F_REVERSE
;
add_hosts_entry
(
cache
,
&
addr
,
addrlen
,
flags
);
}
if
((
cache
=
malloc
(
sizeof
(
struct
crec
)
+
strlen
(
token
)
+
1
-
SMALLDNAME
)))
{
strcpy
(
cache
->
name
.
sname
,
token
);
add_hosts_entry
(
cache
,
&
addr
,
addrlen
,
flags
|
addn_flag
);
/* Clear this here in case not done above. */
flags
&=
~
F_REVERSE
;
add_hosts_entry
(
cache
,
&
addr
,
addrlen
,
flags
);
}
}
else
...
...
@@ -604,7 +605,7 @@ void cache_reload(int opts, char *buff, char *domain_suffix, char *addn_hosts)
read_hostsfile
(
HOSTSFILE
,
opts
,
buff
,
domain_suffix
,
0
);
if
(
addn_hosts
)
{
read_hostsfile
(
addn_hosts
,
opts
,
buff
,
domain_suffix
,
F_ADDN
);
read_hostsfile
(
addn_hosts
,
opts
,
buff
,
domain_suffix
,
1
);
addn_file
=
addn_hosts
;
}
}
...
...
src/config.h
View file @
de37951c
...
...
@@ -12,7 +12,7 @@
/* Author's email: simon@thekelleys.org.uk */
#define VERSION "2.
8
"
#define VERSION "2.
9
"
#define FTABSIZ 150
/* max number of outstanding requests */
#define TIMEOUT 20
/* drop queries after TIMEOUT seconds */
...
...
@@ -59,17 +59,6 @@
#endif
/* determine if we can find the destination address of recieved packets
and set the source address of sent ones. If so, we can use one socket
bound to INADDR_ANY and cope with dynamically created interfaces.
Linux does this differently to FreeBSD. */
#if defined(IP_PKTINFO) || (defined(IP_RECVDSTADDR) && defined(IP_RECVIF) && defined(IP_SENDSRCADDR))
# define HAVE_UDP_SRC_DST
#else
# undef HAVE_UDP_SRC_DST
#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 */
...
...
src/dhcp.c
View file @
de37951c
...
...
@@ -129,13 +129,9 @@ void dhcp_packet(struct dhcp_context *contexts, char *packet,
return
;
#else
if
(
!
names
||
!
names
->
name
||
names
->
next
)
{
syslog
(
LOG_ERR
,
"must set exactly one interface on broken systems without IP_RECVIF"
);
return
;
}
else
strcpy
(
ifr
.
ifr_name
,
names
->
name
);
while
(
names
->
isloop
)
names
=
names
->
next
;
strcpy
(
ifr
.
ifr_name
,
names
->
name
);
#endif
#ifdef HAVE_BPF
...
...
@@ -572,7 +568,7 @@ struct dhcp_config *dhcp_read_ethers(struct dhcp_config *configs, char *buff)
config
->
addr
=
addr
;
}
config
->
flags
|=
CONFIG_HWADDR
;
config
->
flags
|=
CONFIG_HWADDR
|
CONFIG_NOCLID
;
memcpy
(
config
->
hwaddr
,
hwaddr
,
ETHER_ADDR_LEN
);
count
++
;
...
...
src/dnsmasq.c
View file @
de37951c
...
...
@@ -37,15 +37,16 @@ int main (int argc, char **argv)
int
maxleases
=
MAXLEASES
;
int
query_port
=
0
;
int
first_loop
=
1
;
int
bind_fallback
=
0
;
unsigned
long
local_ttl
=
0
;
unsigned
int
options
,
min_leasetime
;
char
*
runfile
=
RUNFILE
;
time_t
resolv_changed
=
0
;
time_t
now
,
last
=
0
;
struct
irec
*
interfaces
=
NULL
;
struct
listener
*
listener
,
*
listeners
;
struct
listener
*
listener
,
*
listeners
=
NULL
;
struct
doctor
*
doctors
=
NULL
;
char
*
mxname
=
NULL
;
struct
mx_record
*
mxnames
=
NULL
;
char
*
mxtarget
=
NULL
;
char
*
lease_file
=
NULL
;
char
*
addn_hosts
=
NULL
;
...
...
@@ -106,7 +107,7 @@ int main (int argc, char **argv)
packet
=
safe_malloc
(
DNSMASQ_PACKETSZ
);
dhcp_next_server
.
s_addr
=
0
;
options
=
read_opts
(
argc
,
argv
,
dnamebuff
,
&
resolv
,
&
mxname
,
&
mxtarget
,
&
lease_file
,
options
=
read_opts
(
argc
,
argv
,
dnamebuff
,
&
resolv
,
&
mxname
s
,
&
mxtarget
,
&
lease_file
,
&
username
,
&
groupname
,
&
domain_suffix
,
&
runfile
,
&
if_names
,
&
if_addrs
,
&
if_except
,
&
bogus_addr
,
&
serv_addrs
,
&
cachesize
,
&
port
,
&
query_port
,
&
local_ttl
,
&
addn_hosts
,
...
...
@@ -124,18 +125,41 @@ int main (int argc, char **argv)
die
(
"ISC dhcpd integration not available: set HAVE_ISC_READER in src/config.h"
,
NULL
);
#endif
#ifndef HAVE_UDP_SRC_DST
/* if we cannot support binding the wildcard address, set the "bind only
interfaces in use" option */
options
|=
OPT_NOWILD
;
#endif
interfaces
=
enumerate_interfaces
(
&
if_names
,
&
if_addrs
,
if_except
,
port
);
if
(
options
&
OPT_NOWILD
)
listeners
=
create_bound_listeners
(
interfaces
);
else
listeners
=
create_wildcard_listeners
(
port
);
if
(
!
(
options
&
OPT_NOWILD
)
&&
!
(
listeners
=
create_wildcard_listeners
(
port
)))
{
bind_fallback
=
1
;
options
|=
OPT_NOWILD
;
}
if
(
options
&
OPT_NOWILD
)
{
struct
iname
*
if_tmp
;
listeners
=
create_bound_listeners
(
interfaces
);
for
(
if_tmp
=
if_names
;
if_tmp
;
if_tmp
=
if_tmp
->
next
)
if
(
if_tmp
->
name
&&
!
if_tmp
->
used
)
die
(
"unknown interface %s"
,
if_tmp
->
name
);
for
(
if_tmp
=
if_addrs
;
if_tmp
;
if_tmp
=
if_tmp
->
next
)
if
(
!
if_tmp
->
used
)
{
char
addrbuff
[
ADDRSTRLEN
];
#ifdef HAVE_IPV6
if
(
if_tmp
->
addr
.
sa
.
sa_family
==
AF_INET
)
inet_ntop
(
AF_INET
,
&
if_tmp
->
addr
.
in
.
sin_addr
,
addrbuff
,
ADDRSTRLEN
);
else
inet_ntop
(
AF_INET6
,
&
if_tmp
->
addr
.
in6
.
sin6_addr
,
addrbuff
,
ADDRSTRLEN
);
#else
strcpy
(
addrbuff
,
inet_ntoa
(
if_tmp
->
addr
.
in
.
sin_addr
));
#endif
die
(
"no interface with address %s"
,
addrbuff
);
}
}
forward_init
(
1
);
cache_init
(
cachesize
,
options
&
OPT_LOG
);
...
...
@@ -148,6 +172,15 @@ int main (int argc, char **argv)
if
(
dhcp
)
{
#if !defined(IP_PKTINFO) && !defined(IP_RECVIF)
int
c
;
struct
iname
*
tmp
;
for
(
c
=
0
,
tmp
=
if_names
;
tmp
;
tmp
=
tmp
->
next
)
if
(
!
tmp
->
isloop
)
c
++
;
if
(
c
!=
1
)
die
(
"must set exactly one interface on broken systems without IP_RECVIF"
,
NULL
);
#endif
dhcp_init
(
&
dhcpfd
,
&
dhcp_raw_fd
);
leasefd
=
lease_init
(
lease_file
,
domain_suffix
,
dnamebuff
,
packet
,
now
,
maxleases
);
}
...
...
@@ -228,12 +261,9 @@ int main (int argc, char **argv)
else
syslog
(
LOG_INFO
,
"started, version %s cache disabled"
,
VERSION
);
if
(
options
&
OPT_LOCALMX
)
syslog
(
LOG_INFO
,
"serving MX record for local hosts target %s"
,
mxtarget
);
else
if
(
mxname
)
syslog
(
LOG_INFO
,
"serving MX record for mailhost %s target %s"
,
mxname
,
mxtarget
);
if
(
bind_fallback
)
syslog
(
LOG_WARNING
,
"setting --bind-interfaces option because if OS limitations"
);
for
(
dhcp_tmp
=
dhcp
;
dhcp_tmp
;
dhcp_tmp
=
dhcp_tmp
->
next
)
{
strcpy
(
dnamebuff
,
inet_ntoa
(
dhcp_tmp
->
start
));
...
...
@@ -256,8 +286,9 @@ int main (int argc, char **argv)
if
(
getuid
()
==
0
||
geteuid
()
==
0
)
syslog
(
LOG_WARNING
,
"failed to drop root privs"
);
servers
=
last_server
=
check_servers
(
serv_addrs
,
interfaces
,
&
sfds
);
servers
=
check_servers
(
serv_addrs
,
interfaces
,
&
sfds
);
last_server
=
NULL
;
while
(
sigterm
==
0
)
{
fd_set
rset
;
...
...
@@ -275,9 +306,11 @@ int main (int argc, char **argv)
lease_update_dns
();
}
if
(
resolv
&&
(
options
&
OPT_NO_POLL
))
servers
=
last_server
=
check_servers
(
reload_servers
(
resolv
->
name
,
dnamebuff
,
servers
,
query_port
),
interfaces
,
&
sfds
);
{
servers
=
check_servers
(
reload_servers
(
resolv
->
name
,
dnamebuff
,
servers
,
query_port
),
interfaces
,
&
sfds
);
last_server
=
NULL
;
}
sighup
=
0
;
}
...
...
@@ -373,7 +406,7 @@ int main (int argc, char **argv)
else
{
res
->
logged
=
0
;
if
(
statbuf
.
st_mtime
>
last_change
)
if
(
difftime
(
statbuf
.
st_mtime
,
last_change
)
>
0
.
0
)
{
last_change
=
statbuf
.
st_mtime
;
latest
=
res
;
...
...
@@ -382,20 +415,20 @@ int main (int argc, char **argv)
res
=
res
->
next
;
}
if
(
latest
&&
last_change
>
resolv_changed
)
if
(
latest
&&
difftime
(
last_change
,
resolv_changed
)
>
0
.
0
)
{
resolv_changed
=
last_change
;
servers
=
last_server
=
check_servers
(
reload_servers
(
latest
->
name
,
dnamebuff
,
servers
,
query_port
),
interfaces
,
&
sfds
)
;
servers
=
check_servers
(
reload_servers
(
latest
->
name
,
dnamebuff
,
servers
,
query_port
),
interfaces
,
&
sfds
);
last_server
=
NULL
;
}
}
}
for
(
serverfdp
=
sfds
;
serverfdp
;
serverfdp
=
serverfdp
->
next
)
if
(
FD_ISSET
(
serverfdp
->
fd
,
&
rset
))
last_server
=
reply_query
(
serverfdp
->
fd
,
options
,
packet
,
now
,
dnamebuff
,
last_server
,
bogus_addr
,
doctors
);
last_server
=
reply_query
(
serverfdp
,
options
,
packet
,
now
,
dnamebuff
,
servers
,
last_server
,
bogus_addr
,
doctors
);
if
(
dhcp
&&
FD_ISSET
(
dhcpfd
,
&
rset
))
dhcp_packet
(
dhcp
,
packet
,
dhcp_options
,
dhcp_configs
,
dhcp_vendors
,
...
...
@@ -406,7 +439,7 @@ int main (int argc, char **argv)
for
(
listener
=
listeners
;
listener
;
listener
=
listener
->
next
)
if
(
FD_ISSET
(
listener
->
fd
,
&
rset
))
last_server
=
receive_query
(
listener
,
packet
,
mxname
,
mxtarget
,
options
,
now
,
local_ttl
,
dnamebuff
,
mxname
s
,
mxtarget
,
options
,
now
,
local_ttl
,
dnamebuff
,
if_names
,
if_addrs
,
if_except
,
last_server
,
servers
);
}
...
...
src/dnsmasq.h
View file @
de37951c
...
...
@@ -56,7 +56,7 @@
#include <errno.h>
#include <pwd.h>
#include <grp.h>
#if defined(__OpenBSD__)
#if defined(__OpenBSD__)
|| defined(__NetBSD__)
# include <netinet/if_ether.h>
#else
# include <net/ethernet.h>
...
...
@@ -91,6 +91,7 @@
#define OPT_NODOTS_LOCAL 4096
#define OPT_NOWILD 8192
#define OPT_ETHERS 16384
#define OPT_RESOLV_DOMAIN 32768
struct
all_addr
{
union
{
...
...
@@ -112,6 +113,11 @@ struct doctor {
struct
doctor
*
next
;
};
struct
mx_record
{
char
*
mxname
,
*
mxtarget
;
struct
mx_record
*
next
;
};
union
bigname
{
char
name
[
MAXDNAME
];
union
bigname
*
next
;
/* freelist */
...
...
@@ -206,6 +212,7 @@ struct listener {
struct
iname
{
char
*
name
;
union
mysockaddr
addr
;
int
isloop
,
used
;
struct
iname
*
next
;
};
...
...
@@ -337,7 +344,7 @@ int setup_reply(HEADER *header, unsigned int qlen,
void
extract_addresses
(
HEADER
*
header
,
unsigned
int
qlen
,
char
*
namebuff
,
time_t
now
,
struct
doctor
*
doctors
);
void
extract_neg_addrs
(
HEADER
*
header
,
unsigned
int
qlen
,
char
*
namebuff
,
time_t
now
);
int
answer_request
(
HEADER
*
header
,
char
*
limit
,
unsigned
int
qlen
,
char
*
mxname
,
int
answer_request
(
HEADER
*
header
,
char
*
limit
,
unsigned
int
qlen
,
struct
mx_record
*
mxnames
,
char
*
mxtarget
,
unsigned
int
options
,
time_t
now
,
unsigned
long
local_ttl
,
char
*
namebuff
);
int
check_for_bogus_wildcard
(
HEADER
*
header
,
unsigned
int
qlen
,
char
*
name
,
...
...
@@ -360,7 +367,7 @@ int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask);
/* option.c */
unsigned
int
read_opts
(
int
argc
,
char
**
argv
,
char
*
buff
,
struct
resolvc
**
resolv_file
,
char
**
mxname
,
char
**
mxtarget
,
char
**
lease_file
,
struct
mx_record
**
mxnames
,
char
**
mxtarget
,
char
**
lease_file
,
char
**
username
,
char
**
groupname
,
char
**
domain_suffix
,
char
**
runfile
,
struct
iname
**
if_names
,
struct
iname
**
if_addrs
,
struct
iname
**
if_except
,
...
...
@@ -373,11 +380,11 @@ unsigned int read_opts(int argc, char **argv, char *buff, struct resolvc **resol
/* forward.c */
void
forward_init
(
int
first
);
struct
server
*
reply_query
(
int
fd
,
int
options
,
char
*
packet
,
time_t
now
,
char
*
dnamebuff
,
struct
server
*
last_server
,
struct
server
*
reply_query
(
struct
serverfd
*
s
fd
,
int
options
,
char
*
packet
,
time_t
now
,
char
*
dnamebuff
,
struct
server
*
servers
,
struct
server
*
last_server
,
struct
bogus_addr
*
bogus_nxdomain
,
struct
doctor
*
doctors
);
struct
server
*
receive_query
(
struct
listener
*
listen
,
char
*
packet
,
char
*
mxname
,
struct
server
*
receive_query
(
struct
listener
*
listen
,
char
*
packet
,
struct
mx_record
*
mxnames
,
char
*
mxtarget
,
unsigned
int
options
,
time_t
now
,
unsigned
long
local_ttl
,
char
*
namebuff
,
struct
iname
*
names
,
struct
iname
*
addrs
,
struct
iname
*
except
,
...
...
src/forward.c
View file @
de37951c
This diff is collapsed.
Click to expand it.
src/network.c
View file @
de37951c
...
...
@@ -30,14 +30,17 @@ static struct irec *add_iface(struct irec *list, char *name, union mysockaddr *a
/* we may need to check the whitelist */
if
(
names
||
addrs
)
{
int
found
=
0
;
for
(
tmp
=
names
;
tmp
;
tmp
=
tmp
->
next
)
if
(
tmp
->
name
&&
(
strcmp
(
tmp
->
name
,
name
)
==
0
))
break
;
if
(
!
tmp
)
for
(
tmp
=
addrs
;
tmp
;
tmp
=
tmp
->
next
)
if
(
sockaddr_isequal
(
&
tmp
->
addr
,
addr
))
break
;
if
(
!
tmp
)
found
=
tmp
->
used
=
1
;
for
(
tmp
=
addrs
;
tmp
;
tmp
=
tmp
->
next
)
if
(
sockaddr_isequal
(
&
tmp
->
addr
,
addr
))
found
=
tmp
->
used
=
1
;
if
(
!
found
)
return
list
;
}
...
...
@@ -72,7 +75,7 @@ struct irec *enumerate_interfaces(struct iname **names,
if
(
fd
==
-
1
)
die
(
"cannot create socket to enumerate interfaces: %s"
,
NULL
);
while
(
1
)
{
buf
=
safe_malloc
(
len
);
...
...
@@ -137,15 +140,24 @@ struct irec *enumerate_interfaces(struct iname **names,
die
(
"ioctl error getting interface flags: %m"
,
NULL
);
/* If we are restricting the set of interfaces to use, make
sure that loopback interfaces are in that set. Note that
this is done as addresses rather than interface names so
as not to confuse the no-IPRECVIF workaround on the DHCP code */
sure that loopback interfaces are in that set. */
if
(
*
names
&&
(
ifr
->
ifr_flags
&
IFF_LOOPBACK
))
{
struct
iname
*
lo
=
safe_malloc
(
sizeof
(
struct
iname
));
lo
->
addr
=
addr
;
lo
->
next
=
*
addrs
;
*
addrs
=
lo
;
struct
iname
*
lo
;
for
(
lo
=
*
names
;
lo
;
lo
=
lo
->
next
)
if
(
lo
->
name
&&
strcmp
(
lo
->
name
,
ifr
->
ifr_name
)
==
0
)
{
lo
->
isloop
=
1
;
break
;
}
if
(
!
lo
)
{
lo
=
safe_malloc
(
sizeof
(
struct
iname
));
lo
->
name
=
safe_string_alloc
(
ifr
->
ifr_name
);
lo
->
isloop
=
lo
->
used
=
1
;
lo
->
next
=
*
names
;
*
names
=
lo
;
}
}
iface
=
add_iface
(
iface
,
ifr
->
ifr_name
,
&
addr
,
*
names
,
*
addrs
,
except
);
...
...
@@ -192,17 +204,7 @@ struct irec *enumerate_interfaces(struct iname **names,
}
if
(
found
)
{
if
(
*
names
&&
(
ifr
->
ifr_flags
&
IFF_LOOPBACK
))
{
struct
iname
*
lo
=
safe_malloc
(
sizeof
(
struct
iname
));
lo
->
addr
=
addr6
;
lo
->
next
=
*
addrs
;
*
addrs
=
lo
;
}
iface
=
add_iface
(
iface
,
ifr
->
ifr_name
,
&
addr6
,
*
names
,
*
addrs
,
except
);
}
iface
=
add_iface
(
iface
,
ifr
->
ifr_name
,
&
addr6
,
*
names
,
*
addrs
,
except
);
}
#endif
/* LINUX */
}
...
...
@@ -220,6 +222,9 @@ struct irec *enumerate_interfaces(struct iname **names,
struct
listener
*
create_wildcard_listeners
(
int
port
)
{
#if !(defined(IP_PKTINFO) || (defined(IP_RECVDSTADDR) && defined(IP_RECVIF) && defined(IP_SENDSRCADDR)))
return
NULL
;
#else
union
mysockaddr
addr
;
int
opt
=
1
;
struct
listener
*
listen
;
...
...
@@ -235,7 +240,10 @@ struct listener *create_wildcard_listeners(int port)
#endif
listen
=
safe_malloc
(
sizeof
(
struct
listener
));
if
((
listen
->
fd
=
socket
(
AF_INET
,
SOCK_DGRAM
,
0
))
==
-
1
)
die
(
"failed to create socket: %s"
,
NULL
);
{
free
(
listen
);
return
NULL
;
}
if
(
setsockopt
(
listen
->
fd
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
opt
,
sizeof
(
opt
))
==
-
1
||
#if defined(IP_PKTINFO)
setsockopt
(
listen
->
fd
,
SOL_IP
,
IP_PKTINFO
,
&
opt
,
sizeof
(
opt
))
==
-
1
||
...
...
@@ -244,7 +252,11 @@ struct listener *create_wildcard_listeners(int port)
setsockopt
(
listen
->
fd
,
IPPROTO_IP
,
IP_RECVIF
,
&
opt
,
sizeof
(
opt
))
==
-
1
||
#endif
bind
(
listen
->
fd
,
(
struct
sockaddr
*
)
&
addr
,
sa_len
(
&
addr
))
==
-
1
)
die
(
"failed to bind socket: %s"
,
NULL
);
{
close
(
listen
->
fd
);
free
(
listen
);
return
NULL
;
}
listen
->
next
=
NULL
;
listen
->
family
=
AF_INET
;
#ifdef HAVE_IPV6
...
...
@@ -260,7 +272,11 @@ struct listener *create_wildcard_listeners(int port)
if
(
errno
!=
EPROTONOSUPPORT
&&
errno
!=
EAFNOSUPPORT
&&
errno
!=
EINVAL
)
die
(
"failed to create IPv6 socket: %s"
,
NULL
);
{
close
(
listen
->
fd
);
free
(
listen
);
return
NULL
;
}
}
else
{
...
...
@@ -271,11 +287,19 @@ struct listener *create_wildcard_listeners(int port)
if
(
setsockopt
(
listen
->
next
->
fd
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
opt
,
sizeof
(
opt
))
==
-
1
||
setsockopt
(
listen
->
next
->
fd
,
IPV6_LEVEL
,
IPV6_PKTINFO
,
&
opt
,
sizeof
(
opt
))
==
-
1
||
bind
(
listen
->
next
->
fd
,
(
struct
sockaddr
*
)
&
addr
,
sa_len
(
&
addr
))
==
-
1
)
die
(
"failed to bind IPv6 socket: %s"
,
NULL
);
{
close
(
listen
->
next
->
fd
);
free
(
listen
->
next
);
close
(
listen
->
fd
);
free
(
listen
);
return
NULL
;
}
}
#endif
return
listen
;
#endif
}
struct
listener
*
create_bound_listeners
(
struct
irec
*
interfaces
)
...
...
@@ -455,7 +479,7 @@ struct server *reload_servers(char *fname, char *buff, struct server *serv, int
if
(
!
token
||
strcmp
(
token
,
"nameserver"
)
!=
0
)
continue
;
if
(
!
(
token
=
strtok
(
NULL
,
"
\t\n
"
)))
if
(
!
(
token
=
strtok
(
NULL
,
"
\t\n
\r
"
)))
continue
;
#ifdef HAVE_IPV6
...
...
src/option.c
View file @
de37951c
...
...
@@ -154,7 +154,7 @@ static char *usage =
unsigned
int
read_opts
(
int
argc
,
char
**
argv
,
char
*
buff
,
struct
resolvc
**
resolv_files
,
char
**
mxname
,
char
**
mxtarget
,
char
**
lease_file
,
struct
mx_record
**
mxnames
,
char
**
mxtarget
,
char
**
lease_file
,
char
**
username
,
char
**
groupname
,
char
**
domain_suffix
,
char
**
runfile
,
struct
iname
**
if_names
,
struct
iname
**
if_addrs
,
struct
iname
**
if_except
,
struct
bogus_addr
**
bogus_addr
,
struct
server
**
serv_addrs
,
int
*
cachesize
,
int
*
port
,
...
...
@@ -346,11 +346,22 @@ unsigned int read_opts (int argc, char **argv, char *buff, struct resolvc **reso
}
case
'm'
:
if
(
!
canonicalise
(
optarg
))
option
=
'?'
;
else
*
mxname
=
safe_string_alloc
(
optarg
);
break
;
{
char
*
comma
=
strchr
(
optarg
,
','
);
if
(
comma
)
*
(
comma
++
)
=
0
;
if
(
!
canonicalise
(
optarg
)
||
(
comma
&&
!
canonicalise
(
comma
)))
option
=
'?'
;
else
{
struct
mx_record
*
new
=
safe_malloc
(
sizeof
(
struct
mx_record
));
new
->
next
=
*
mxnames
;
*
mxnames
=
new
;
new
->
mxname
=
safe_string_alloc
(
optarg
);
new
->
mxtarget
=
safe_string_alloc
(
comma
);
/* may be NULL */
}
break
;
}
case
't'
:
if
(
!
canonicalise
(
optarg
))
...
...
@@ -371,7 +382,9 @@ unsigned int read_opts (int argc, char **argv, char *buff, struct resolvc **reso
break
;
case
's'
:
if
(
!
canonicalise
(
optarg
))
if
(
strcmp
(
optarg
,
"#"
)
==
0
)
flags
|=
OPT_RESOLV_DOMAIN
;
else
if
(
!
canonicalise
(
optarg
))
option
=
'?'
;
else
*
domain_suffix
=
safe_string_alloc
(
optarg
);
...
...
@@ -393,6 +406,7 @@ unsigned int read_opts (int argc, char **argv, char *buff, struct resolvc **reso
/* new->name may be NULL if someone does
"interface=" to disable all interfaces except loop. */
new
->
name
=
safe_string_alloc
(
optarg
);
new
->
isloop
=
new
->
used
=
0
;
if
(
strchr
(
optarg
,
':'
))
flags
|=
OPT_NOWILD
;
break
;
...
...
@@ -481,7 +495,7 @@ unsigned int read_opts (int argc, char **argv, char *buff, struct resolvc **reso
/* # matches everything and becomes a zero length domain string */
if
(
strcmp
(
optarg
,
"#"
)
==
0
)
domain
=
""
;
else
if
(
!
canonicalise
(
optarg
))
else
if
(
!
canonicalise
(
optarg
)
&&
strlen
(
optarg
)
!=
0
)
option
=
'?'
;
else
domain
=
safe_string_alloc
(
optarg
);
/* NULL if strlen is zero */
...
...
@@ -1191,13 +1205,18 @@ unsigned int read_opts (int argc, char **argv, char *buff, struct resolvc **reso
/* only one of these need be specified: the other defaults to the
host-name */
if
((
flags
&
OPT_LOCALMX
)
||
*
mxname
||
*
mxtarget
)
if
((
flags
&
OPT_LOCALMX
)
||
*
mxname
s
||
*
mxtarget
)
{
if
(
gethostname
(
buff
,
MAXDNAME
)
==
-
1
)
die
(
"cannot get host-name: %s"
,
NULL
);
if
(
!*
mxname
)
*
mxname
=
safe_string_alloc
(
buff
);
if
(
!*
mxnames
)
{
*
mxnames
=
safe_malloc
(
sizeof
(
struct
mx_record
));
(
*
mxnames
)
->
next
=
NULL
;
(
*
mxnames
)
->
mxtarget
=
NULL
;
(
*
mxnames
)
->
mxname
=
safe_string_alloc
(
buff
);
}
if
(
!*
mxtarget
)
*
mxtarget
=
safe_string_alloc
(
buff
);
...
...
@@ -1207,7 +1226,36 @@ unsigned int read_opts (int argc, char **argv, char *buff, struct resolvc **reso
*
resolv_files
=
0
;
else
if
(
*
resolv_files
&&
(
*
resolv_files
)
->
next
&&
(
flags
&
OPT_NO_POLL
))
die
(
"only one resolv.conf file allowed in no-poll mode."
,
NULL
);
if
(
flags
&
OPT_RESOLV_DOMAIN
)
{
char
*
line
;
if
(
!*
resolv_files
||
(
*
resolv_files
)
->
next
)
die
(
"must have exactly one resolv.conf to read domain from."
,
NULL
);
if
(
!
(
f
=
fopen
((
*
resolv_files
)
->
name
,
"r"
)))
die
(
"failed to read %s: %m"
,
(
*
resolv_files
)
->
name
);
while
((
line
=
fgets
(
buff
,
MAXDNAME
,
f
)))
{
char
*
token
=
strtok
(
line
,
"
\t\n\r
"
);
if
(
!
token
||
strcmp
(
token
,
"search"
)
!=
0
)
continue
;
if
((
token
=
strtok
(
NULL
,
"
\t\n\r
"
))
&&
canonicalise
(
token
)
&&
(
*
domain_suffix
=
safe_string_alloc
(
token
)))
break
;
}
fclose
(
f
);
if
(
!*
domain_suffix
)
die
(
"no search directive found in %s"
,
(
*
resolv_files
)
->
name
);
}
return
flags
;
}
...
...
src/rfc1035.c
View file @
de37951c
...
...
@@ -728,7 +728,7 @@ int check_for_bogus_wildcard(HEADER *header, unsigned int qlen, char *name,
}
/* return zero if we can't answer from cache, or packet size if we can */
int
answer_request
(
HEADER
*
header
,
char
*
limit
,
unsigned
int
qlen
,
char
*
mxname
,
int
answer_request
(
HEADER
*
header
,
char
*
limit
,
unsigned
int
qlen
,
struct
mx_record
*
mxnames
,
char
*
mxtarget
,
unsigned
int
options
,
time_t
now
,
unsigned
long
local_ttl
,
char
*
name
)
{
...
...
@@ -988,9 +988,14 @@ int answer_request(HEADER *header, char *limit, unsigned int qlen, char *mxname,
if
(
qtype
==
T_MX
||
qtype
==
T_ANY
)
{
if
(
mxname
&&
hostname_isequal
(
name
,
mxname
))
struct
mx_record
*
mx
;
for
(
mx
=
mxnames
;
mx
;
mx
=
mx
->
next
)
if
(
hostname_isequal
(
name
,
mx
->
mxname
))
break
;
if
(
mx
)
{
ansp
=
add_text_record
(
nameoffset
,
ansp
,
local_ttl
,
1
,
T_MX
,
mxtarget
);
ansp
=
add_text_record
(
nameoffset
,
ansp
,
local_ttl
,
1
,
T_MX
,
mx
->
mxtarget
?
mx
->
mxtarget
:
mxtarget
);
anscount
++
;
ans
=
1
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment