Commit 3be34541 authored by Simon Kelley's avatar Simon Kelley

import of dnsmasq-2.14.tar.gz

parent 9c74ec03
...@@ -1160,3 +1160,33 @@ version 2.12 ...@@ -1160,3 +1160,33 @@ version 2.12
version 2.13 version 2.13
Fixed crash with un-named DHCP hosts introduced in 2.12. Fixed crash with un-named DHCP hosts introduced in 2.12.
Thanks to Nicolo Wojewoda and Gregory Gathy for bug reports. Thanks to Nicolo Wojewoda and Gregory Gathy for bug reports.
version 2.14
Fix DHCP network detection for hosts which talk via a
relay. This makes lease renewal for such hosts work
correctly.
Support RFC3011 subnet selectors in the DHCP server.
Fix DHCP code to generate RFC-compliant responses
to hosts in the INIT-REBOOT state.
In the DHCP server, set the receive buffer size on
the transmit-only packet socket to zero, to avoid
waste of kernel buffers.
Fix DHCP address allocation code to use the whole of
the DHCP range, including the start and end addresses.
Attempt an ICMP "ping" on new addresses before allocating
them to leases, to avoid allocating addresses which are in use.
Handle rfc951 BOOTP as well as DHCP for hosts which have
MAC address to IP address mapping defined.
Fix compilation under MacOS X. Thanks to Chris Tomlinson.
Fix compilation under NetBSD. Thanks to Felix Deichmann.
Added "keep-in-foreground" option. Thanks to Sean
MacLennan for the patch.
...@@ -190,7 +190,8 @@ A: By default, none of the DHCP clients send the host-name when asking ...@@ -190,7 +190,8 @@ A: By default, none of the DHCP clients send the host-name when asking
send with the "hostname" keyword in /etc/network/interfaces. (See send with the "hostname" keyword in /etc/network/interfaces. (See
"man interfaces" for details.) That doesn't work for dhclient, were "man interfaces" for details.) That doesn't work for dhclient, were
you have to add something like "send host-name daisy" to you have to add something like "send host-name daisy" to
/etc/dhclient.conf /etc/dhclient.conf [Update: the lastest dhcpcd packages _do_ send
the hostname by default.
Q: I'm network booting my machines, and trying to give them static Q: I'm network booting my machines, and trying to give them static
DHCP-assigned addresses. The machine gets its correct address DHCP-assigned addresses. The machine gets its correct address
...@@ -276,5 +277,13 @@ A: Probably because you have the "filterwin2k" option set. Note that ...@@ -276,5 +277,13 @@ A: Probably because you have the "filterwin2k" option set. Note that
versions before 2.12, so you might have it set on without versions before 2.12, so you might have it set on without
realising. realising.
Q: Can I get email notification when a new version of dnsmasq is
released?
A: Yes, new releases of dnsmasq are always announced through
freshmeat.net, and they allow you to subcribe to email alerts when
new versions of particular projects are released.
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
############################################################################### ###############################################################################
Name: dnsmasq Name: dnsmasq
Version: 2.13 Version: 2.14
Release: 1 Release: 1
Copyright: GPL Copyright: GPL
Group: System Environment/Daemons Group: System Environment/Daemons
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
############################################################################### ###############################################################################
Name: dnsmasq Name: dnsmasq
Version: 2.13 Version: 2.14
Release: 1 Release: 1
Copyright: GPL Copyright: GPL
Group: Productivity/Networking/DNS/Servers Group: Productivity/Networking/DNS/Servers
......
...@@ -15,12 +15,13 @@ contents of /etc/hosts so that local hostnames ...@@ -15,12 +15,13 @@ contents of /etc/hosts so that local hostnames
which do not appear in the global DNS can be resolved and also answers which do not appear in the global DNS can be resolved and also answers
DNS queries for DHCP configured hosts. DNS queries for DHCP configured hosts.
.PP .PP
.BR dnsmasq The dnsmasq DHCP server supports static address assignments, multiple
supports IPv6. networks, DHCP-relay and RFC3011 subnet specifiers. It automatically
sends a sensible default set of DHCP options, and can be configured to
send any desired set of DHCP options. It also supports BOOTP.
.PP .PP
.BR dnsmasq Dnsmasq
is lightweight and easy to configure. It is intended as be run on supports IPv6.
small router/firewalls and provide a DNS (and optionally, DHCP) service to a LAN.
.SH OPTIONS .SH OPTIONS
Note that in general missing parameters are allowed and switch off Note that in general missing parameters are allowed and switch off
functions, for instance "--pid-file=" disables writing a PID file. On functions, for instance "--pid-file=" disables writing a PID file. On
...@@ -45,10 +46,15 @@ time-to-live (in seconds) to be given for these replies. This will ...@@ -45,10 +46,15 @@ time-to-live (in seconds) to be given for these replies. This will
reduce the load on the server at the expense of clients using stale reduce the load on the server at the expense of clients using stale
data under some circumstances. data under some circumstances.
.TP .TP
.B \-k, --keep-in-foreground
Do not go into the background at startup but otherwise run as
normal. This is intended for use when dnsmasq is run under daemontools.
.TP
.B \-d, --no-daemon .B \-d, --no-daemon
Debug mode: don't fork to the background, don't write a pid file, Debug mode: don't fork to the background, don't write a pid file,
don't change user id, generate a complete cache dump on receipt on don't change user id, generate a complete cache dump on receipt on
SIGUSR1, log to stderr as well as syslog. SIGUSR1, log to stderr as well as syslog, don't fork new processes
to handle TCP queries.
.TP .TP
.B \-q, --log-queries .B \-q, --log-queries
Log the results of DNS queries handled by dnsmasq. Enable a full cache dump on receipt of SIGUSR1. Log the results of DNS queries handled by dnsmasq. Enable a full cache dump on receipt of SIGUSR1.
...@@ -441,8 +447,12 @@ in /etc/resolv.conf (or equivalent). ...@@ -441,8 +447,12 @@ in /etc/resolv.conf (or equivalent).
Add the domain-suffix to simple names (without a period) in /etc/hosts Add the domain-suffix to simple names (without a period) in /etc/hosts
in the same way as for DHCP-derived names. in the same way as for DHCP-derived names.
.SH CONFIG FILE .SH CONFIG FILE
At startup, dnsmasq reads /etc/dnsmasq.conf, if it exists. (On At startup, dnsmasq reads
FreeBSD and OpenBSD, the file is /usr/local/etc/dnsmasq.conf) The format of this .I /etc/dnsmasq.conf,
if it exists. (On
FreeBSD, the file is
.I /usr/local/etc/dnsmasq.conf
) The format of this
file consists of one option per line, exactly as the long options detailed file consists of one option per line, exactly as the long options detailed
in the OPTIONS section but without the leading "--". Lines starting with # are comments and ignored. For in the OPTIONS section but without the leading "--". Lines starting with # are comments and ignored. For
options which may only be specified once, the configuration file overrides options which may only be specified once, the configuration file overrides
...@@ -453,10 +463,14 @@ level of nesting is allowed. ...@@ -453,10 +463,14 @@ level of nesting is allowed.
.SH NOTES .SH NOTES
When it receives a SIGHUP, When it receives a SIGHUP,
.B dnsmasq .B dnsmasq
clears its cache and then re-loads /etc/hosts. If clears its cache and then re-loads
.I /etc/hosts.
If
.B .B
--no-poll --no-poll
is set SIGHUP also re-reads /etc/resolv.conf. SIGHUP is set SIGHUP also re-reads
.I /etc/resolv.conf.
SIGHUP
does NOT re-read the configuration file. does NOT re-read the configuration file.
.PP .PP
When it receives a SIGUSR1, When it receives a SIGUSR1,
...@@ -472,25 +486,34 @@ Dnsmasq is a DNS query forwarder: it it not capable of recursively ...@@ -472,25 +486,34 @@ Dnsmasq is a DNS query forwarder: it it not capable of recursively
answering arbitrary queries starting from the root servers but answering arbitrary queries starting from the root servers but
forwards such queries to a fully recursive upstream DNS server which is forwards such queries to a fully recursive upstream DNS server which is
typically provided by an ISP. By default, dnsmasq reads typically provided by an ISP. By default, dnsmasq reads
/etc/resolv.conf to discover the IP .I /etc/resolv.conf
to discover the IP
addresses of the upstream nameservers it should use, since the addresses of the upstream nameservers it should use, since the
information is typically stored there. Unless information is typically stored there. Unless
.B --no-poll .B --no-poll
is used, is used,
.B dnsmasq .B dnsmasq
checks the modification time of /etc/resolv.conf (or checks the modification time of
equivalent if .I /etc/resolv.conf
(or equivalent if
.B \--resolv-file .B \--resolv-file
is used) and re-reads it if it changes. This allows the DNS servers to is used) and re-reads it if it changes. This allows the DNS servers to
be set dynamically by PPP or DHCP since both protocols provide the be set dynamically by PPP or DHCP since both protocols provide the
information. information.
Absence of /etc/resolv.conf is not an error Absence of
.I /etc/resolv.conf
is not an error
since it may not have been created before a PPP connection exists. Dnsmasq since it may not have been created before a PPP connection exists. Dnsmasq
simply keeps checking in case /etc/resolv.conf is created at any simply keeps checking in case
.I /etc/resolv.conf
is created at any
time. Dnsmasq can be told to parse more than one resolv.conf time. Dnsmasq can be told to parse more than one resolv.conf
file. This is useful on a laptop, where both PPP and DHCP may be used: file. This is useful on a laptop, where both PPP and DHCP may be used:
dnsmasq can be set to poll both /etc/ppp/resolv.conf and dnsmasq can be set to poll both
/etc/dhcpc/resolv.conf and will use the contents of whichever changed .I /etc/ppp/resolv.conf
and
.I /etc/dhcpc/resolv.conf
and will use the contents of whichever changed
last, giving automatic switching between DNS servers. last, giving automatic switching between DNS servers.
.PP .PP
Upstream servers may also be specified on the command line or in Upstream servers may also be specified on the command line or in
...@@ -510,6 +533,22 @@ and run dnsmasq with the ...@@ -510,6 +533,22 @@ and run dnsmasq with the
.B \-r /etc/resolv.dnsmasq .B \-r /etc/resolv.dnsmasq
option. This second technique allows for dynamic update of the server option. This second technique allows for dynamic update of the server
addresses by PPP or DHCP. addresses by PPP or DHCP.
.PP
The DHCP server in dnsmasq will function as a BOOTP server also,
provided that the MAC address and IP address for clients are given,
either using
.B dhcp-host
configurations or in
.I /etc/ethers
, and a
.B dhcp-range
configuration option is present to activate the DHCP server
on a particular network. The filename
parameter in a BOOTP request is matched against netids in
.B dhcp-option
configurations, allowing some control over the options returned to
different classes of hosts.
.SH FILES .SH FILES
.IR /etc/dnsmasq.conf .IR /etc/dnsmasq.conf
...@@ -519,6 +558,8 @@ addresses by PPP or DHCP. ...@@ -519,6 +558,8 @@ addresses by PPP or DHCP.
.IR /etc/hosts .IR /etc/hosts
.IR /etc/ethers
.IR /var/lib/misc/dnsmasq.leases .IR /var/lib/misc/dnsmasq.leases
.IR /var/db/dnsmasq.leases .IR /var/db/dnsmasq.leases
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
/* Author's email: simon@thekelleys.org.uk */ /* Author's email: simon@thekelleys.org.uk */
#define VERSION "2.13" #define VERSION "2.14"
#define FTABSIZ 150 /* max number of outstanding requests */ #define FTABSIZ 150 /* max number of outstanding requests */
#define MAX_PROCS 20 /* max no children for TCP requests */ #define MAX_PROCS 20 /* max no children for TCP requests */
...@@ -64,6 +64,15 @@ ...@@ -64,6 +64,15 @@
# define DNSMASQ_LOG_FAC(debug) LOG_DAEMON # define DNSMASQ_LOG_FAC(debug) LOG_DAEMON
#endif #endif
/* A small collection of RR-types which are missing on some platforms */
#ifndef T_SRV
# define T_SRV 33
#endif
#ifndef T_OPT
# define T_OPT 41
#endif
/* Decide if we're going to support IPv6 */ /* Decide if we're going to support IPv6 */
/* We assume that systems which don't have IPv6 /* We assume that systems which don't have IPv6
...@@ -218,7 +227,6 @@ NOTES: ...@@ -218,7 +227,6 @@ NOTES:
#undef HAVE_SOCKADDR_SA_LEN #undef HAVE_SOCKADDR_SA_LEN
#undef HAVE_PSELECT #undef HAVE_PSELECT
/* Fix various misfeatures of libc5 headers */ /* Fix various misfeatures of libc5 headers */
#define T_SRV 33
typedef unsigned long in_addr_t; typedef unsigned long in_addr_t;
typedef size_t socklen_t; typedef size_t socklen_t;
...@@ -267,9 +275,8 @@ typedef unsigned long in_addr_t; ...@@ -267,9 +275,8 @@ typedef unsigned long in_addr_t;
#define BIND_8_COMPAT #define BIND_8_COMPAT
/* Define before sys/socket.h is included so we get socklen_t */ /* Define before sys/socket.h is included so we get socklen_t */
#define _BSD_SOCKLEN_T_ #define _BSD_SOCKLEN_T_
/* The two below are not defined in Mac OS X arpa/nameserv.h */ /* The three below are not defined in Mac OS X arpa/nameserv.h */
#define IN6ADDRSZ 16 #define IN6ADDRSZ 16
#define T_SRV 33
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
#undef HAVE_LINUX_IPV6_PROC #undef HAVE_LINUX_IPV6_PROC
......
This diff is collapsed.
This diff is collapsed.
...@@ -27,14 +27,13 @@ ...@@ -27,14 +27,13 @@
/* get this before config.h too. */ /* get this before config.h too. */
#include <syslog.h> #include <syslog.h>
#include <arpa/nameser.h>
#include "config.h" #include "config.h"
#include <arpa/nameser.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/select.h> #include <sys/select.h>
#include <sys/wait.h> #include <sys/wait.h>
...@@ -66,6 +65,7 @@ ...@@ -66,6 +65,7 @@
#include <net/if_arp.h> #include <net/if_arp.h>
#include <netinet/in_systm.h> #include <netinet/in_systm.h>
#include <netinet/ip.h> #include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#ifdef HAVE_BPF #ifdef HAVE_BPF
# include <net/bpf.h> # include <net/bpf.h>
# include <net/if_dl.h> # include <net/if_dl.h>
...@@ -94,6 +94,7 @@ ...@@ -94,6 +94,7 @@
#define OPT_NOWILD 8192 #define OPT_NOWILD 8192
#define OPT_ETHERS 16384 #define OPT_ETHERS 16384
#define OPT_RESOLV_DOMAIN 32768 #define OPT_RESOLV_DOMAIN 32768
#define OPT_NO_FORK 65536
struct all_addr { struct all_addr {
union { union {
...@@ -289,8 +290,9 @@ struct dhcp_vendor { ...@@ -289,8 +290,9 @@ struct dhcp_vendor {
struct dhcp_context { struct dhcp_context {
unsigned int lease_time, addr_epoch; unsigned int lease_time, addr_epoch;
struct in_addr netmask, broadcast; struct in_addr netmask, broadcast, router;
struct in_addr start, end; /* range of available addresses */ struct in_addr start, end; /* range of available addresses */
int static_only;
struct dhcp_netid netid; struct dhcp_netid netid;
struct dhcp_context *next; struct dhcp_context *next;
}; };
...@@ -314,12 +316,57 @@ struct udp_dhcp_packet { ...@@ -314,12 +316,57 @@ struct udp_dhcp_packet {
u16 secs, flags; u16 secs, flags;
struct in_addr ciaddr, yiaddr, siaddr, giaddr; struct in_addr ciaddr, yiaddr, siaddr, giaddr;
u8 chaddr[16], sname[64], file[128]; u8 chaddr[16], sname[64], file[128];
u32 cookie; u8 options[312];
u8 options[308];
} data; } data;
}; };
struct daemon {
/* datastuctures representing the command-line and
config file arguments. All set (including defaults)
in option.c */
unsigned int options;
struct resolvc default_resolv, *resolv_files;
struct mx_record *mxnames;
char *mxtarget;
char *lease_file;
char *username, *groupname;
char *domain_suffix;
char *runfile;
struct iname *if_names, *if_addrs, *if_except;
struct bogus_addr *bogus_addr;
struct server *servers;
int cachesize;
int port, query_port;
unsigned long local_ttl;
char *addn_hosts;
struct dhcp_context *dhcp;
struct dhcp_config *dhcp_conf;
struct dhcp_opt *dhcp_opts;
struct dhcp_vendor *dhcp_vendors;
char *dhcp_file;
char *dhcp_sname;
struct in_addr dhcp_next_server;
int dhcp_max;
unsigned int min_leasetime;
struct doctor *doctors;
unsigned short edns_pktsz;
/* globally used stuff for DNS */
char *packet; /* packet buffer */
char *namebuff; /* MAXDNAME size buffer */
struct serverfd *sfds;
struct listener *listeners;
struct server *last_server;
int uptime_fd;
/* DHCP state */
int dhcpfd, dhcp_raw_fd, dhcp_icmp_fd, lease_fd;
struct udp_dhcp_packet *dhcp_packet;
char *dhcp_buff, *dhcp_buff2;
};
/* cache.c */ /* cache.c */
void cache_init(int cachesize, int log); void cache_init(int cachesize, int log);
void log_query(unsigned short flags, char *name, struct all_addr *addr, unsigned short type); void log_query(unsigned short flags, char *name, struct all_addr *addr, unsigned short type);
...@@ -347,9 +394,7 @@ int setup_reply(HEADER *header, unsigned int qlen, ...@@ -347,9 +394,7 @@ int setup_reply(HEADER *header, unsigned int qlen,
void extract_addresses(HEADER *header, unsigned int qlen, char *namebuff, void extract_addresses(HEADER *header, unsigned int qlen, char *namebuff,
time_t now, struct doctor *doctors); time_t now, struct doctor *doctors);
void extract_neg_addrs(HEADER *header, unsigned int qlen, char *namebuff, time_t now); void extract_neg_addrs(HEADER *header, unsigned int qlen, char *namebuff, time_t now);
int answer_request(HEADER *header, char *limit, unsigned int qlen, struct mx_record *mxnames, int answer_request(HEADER *header, char *limit, unsigned int qlen, struct daemon *daemon, time_t now);
char *mxtarget, unsigned int options, time_t now, unsigned long local_ttl,
char *namebuff, unsigned short edns_pcktsz);
int check_for_bogus_wildcard(HEADER *header, unsigned int qlen, char *name, int check_for_bogus_wildcard(HEADER *header, unsigned int qlen, char *name,
struct bogus_addr *addr, time_t now); struct bogus_addr *addr, time_t now);
unsigned char *find_pseudoheader(HEADER *header, unsigned int plen); unsigned char *find_pseudoheader(HEADER *header, unsigned int plen);
...@@ -370,73 +415,41 @@ time_t dnsmasq_time(int fd); ...@@ -370,73 +415,41 @@ time_t dnsmasq_time(int fd);
int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask); int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask);
/* option.c */ /* option.c */
unsigned int read_opts(int argc, char **argv, char *buff, struct resolvc **resolv_file, struct daemon *read_opts (int argc, char **argv);
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, int *query_port, unsigned long *local_ttl, char **addn_hosts,
struct dhcp_context **dhcp, struct dhcp_config **dhcp_conf,
struct dhcp_opt **opts, struct dhcp_vendor **dhcp_vendors,
char **dhcp_file, char **dhcp_sname, struct in_addr *dhcp_next_server,
int *maxleases, unsigned int *min_leasetime, struct doctor **doctors,
unsigned short *edns_pktsz);
/* forward.c */ /* forward.c */
void forward_init(int first); void forward_init(int first);
struct server *reply_query(struct serverfd *sfd, int options, char *packet, time_t now, void reply_query(struct serverfd *sfd, struct daemon *daemon, time_t now);
char *dnamebuff, struct server *servers, struct server *last_server, void receive_query(struct listener *listen, struct daemon *daemon, time_t now);
struct bogus_addr *bogus_nxdomain, char *tcp_request(struct daemon *daemon, int confd, time_t now);
struct doctor *doctors, unsigned short edns_pcktsz);
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,
struct server *last_server, struct server *servers, unsigned short edns_pcktsz);
char *tcp_request(int confd, struct mx_record *mxnames,
char *mxtarget, unsigned int options, time_t now,
unsigned long local_ttl, char *namebuff,
struct server *last_server, struct server *servers,
struct bogus_addr *bogus_nxdomain, struct doctor *doctors,
unsigned short edns_pcktsz);
/* network.c */ /* network.c */
struct serverfd *allocate_sfd(union mysockaddr *addr, struct serverfd **sfds); struct serverfd *allocate_sfd(union mysockaddr *addr, struct serverfd **sfds);
struct server *reload_servers(char *fname, char *buff, struct server *servers, int query_port); void reload_servers(char *fname, struct daemon *daemon);
struct server *check_servers(struct server *new, struct irec *interfaces, struct serverfd **sfds); void check_servers(struct daemon *daemon, struct irec *interfaces);
struct irec *enumerate_interfaces(struct iname **names, struct irec *enumerate_interfaces(struct daemon *daemon);
struct iname **addrs,
struct iname *except,
int port);
struct listener *create_wildcard_listeners(int port); struct listener *create_wildcard_listeners(int port);
struct listener *create_bound_listeners(struct irec *interfaces, int port); struct listener *create_bound_listeners(struct irec *interfaces, int port);
/* dhcp.c */ /* dhcp.c */
void dhcp_init(int *fdp, int* rfdp, struct dhcp_config *configs); void dhcp_init(struct daemon *daemon);
void dhcp_packet(struct dhcp_context *contexts, char *packet, void dhcp_packet(struct daemon *daemon, time_t now);
struct dhcp_opt *dhcp_opts, struct dhcp_config *dhcp_configs,
struct dhcp_vendor *vendors,
time_t now, char *namebuff, char *domain_suffix,
char *dhcp_file, char *dhcp_sname,
struct in_addr dhcp_next_server, int dhcp_fd, int raw_fd,
struct iname *names, struct iname *addrs, struct iname *except);
int address_available(struct dhcp_context *context, struct in_addr addr); int address_available(struct dhcp_context *context, struct in_addr addr);
int address_allocate(struct dhcp_context *context, struct dhcp_config *configs, int address_allocate(struct dhcp_context *context, struct daemon *daemon,
struct in_addr *addrp, unsigned char *hwaddr); struct in_addr *addrp, unsigned char *hwaddr);
struct dhcp_config *find_config(struct dhcp_config *configs, struct dhcp_config *find_config(struct dhcp_config *configs,
struct dhcp_context *context, struct dhcp_context *context,
unsigned char *clid, int clid_len, unsigned char *clid, int clid_len,
unsigned char *hwaddr, char *hostname); unsigned char *hwaddr, char *hostname);
struct dhcp_config *read_ethers(struct dhcp_config *configs, char *buff);
void dhcp_update_configs(struct dhcp_config *configs); void dhcp_update_configs(struct dhcp_config *configs);
struct dhcp_config *dhcp_read_ethers(struct dhcp_config *configs, char *buff); void dhcp_read_ethers(struct daemon *daemon);
struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct in_addr addr); struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct in_addr addr);
/* lease.c */ /* lease.c */
void lease_update_file(int force, time_t now); void lease_update_file(int force, time_t now);
void lease_update_dns(void); void lease_update_dns(void);
int lease_init(char *lease_file, char *domain, char *buff, void lease_init(struct daemon *daemon, time_t now);
char *buff2, time_t now, int maxleases);
struct dhcp_lease *lease_allocate(unsigned char *clid, int clid_len, struct in_addr addr); struct dhcp_lease *lease_allocate(unsigned char *clid, int clid_len, struct in_addr addr);
void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr); void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr);
void lease_set_hostname(struct dhcp_lease *lease, char *name, char *suffix); void lease_set_hostname(struct dhcp_lease *lease, char *name, char *suffix);
...@@ -447,16 +460,10 @@ void lease_prune(struct dhcp_lease *target, time_t now); ...@@ -447,16 +460,10 @@ void lease_prune(struct dhcp_lease *target, time_t now);
void lease_update_from_configs(struct dhcp_config *dhcp_configs, char *domain); void lease_update_from_configs(struct dhcp_config *dhcp_configs, char *domain);
/* rfc2131.c */ /* rfc2131.c */
int dhcp_reply(struct dhcp_context *context, int dhcp_reply(struct daemon *daemon, struct in_addr iface_addr, char *iface_name, unsigned int sz, time_t now);
struct in_addr iface_addr,
char *iface_name, /* dnsmasq.c */
int iface_mtu, int icmp_ping(struct daemon *daemon, struct in_addr addr);
struct udp_dhcp_packet *rawpacket,
unsigned int sz, time_t now, char *namebuff,
struct dhcp_opt *dhcp_opts, struct dhcp_config *dhcp_configs,
struct dhcp_vendor *vendors,
char *domain_suffix, char *dhcp_file, char *dhcp_sname,
struct in_addr dhcp_next_server, struct in_addr router);
/* isc.c */ /* isc.c */
#ifdef HAVE_ISC_READER #ifdef HAVE_ISC_READER
......
This diff is collapsed.
...@@ -15,12 +15,11 @@ ...@@ -15,12 +15,11 @@
#include "dnsmasq.h" #include "dnsmasq.h"
static struct dhcp_lease *leases; static struct dhcp_lease *leases;
FILE *lease_file; static FILE *lease_file;
int dns_dirty, file_dirty, new_lease; static int dns_dirty, file_dirty, new_lease;
int leases_left; static int leases_left;
int lease_init(char *filename, char *domain, char *buff, void lease_init(struct daemon *daemon, time_t now)
char *buff2, time_t now, int maxleases)
{ {
unsigned int e0, e1, e2, e3, e4, e5, a0, a1, a2, a3; unsigned int e0, e1, e2, e3, e4, e5, a0, a1, a2, a3;
unsigned long ei; unsigned long ei;
...@@ -30,19 +29,22 @@ int lease_init(char *filename, char *domain, char *buff, ...@@ -30,19 +29,22 @@ int lease_init(char *filename, char *domain, char *buff,
struct dhcp_lease *lease; struct dhcp_lease *lease;
int clid_len = 0; int clid_len = 0;
int has_old = 0; int has_old = 0;
char *buff = daemon->dhcp_buff;
char *buff2 = daemon->dhcp_buff2;
leases = NULL; leases = NULL;
leases_left = maxleases; leases_left = daemon->dhcp_max;
/* NOTE: need a+ mode to create file if it doesn't exist */ /* NOTE: need a+ mode to create file if it doesn't exist */
if (!(lease_file = fopen(filename, "a+"))) if (!(lease_file = fopen(daemon->lease_file, "a+")))
die("cannot open or create leases file: %s", NULL); die("cannot open or create leases file: %s", NULL);
/* a+ mode lease pointer at end. */ /* a+ mode lease pointer at end. */
rewind(lease_file); rewind(lease_file);
while (fscanf(lease_file, "%lu %x:%x:%x:%x:%x:%x %d.%d.%d.%d %256s %500s", while (fscanf(lease_file, "%lu %x:%x:%x:%x:%x:%x %d.%d.%d.%d %257s %257s",
&ei, &e0, &e1, &e2, &e3, &e4, &e5, &a0, &a1, &a2, &a3, buff, buff2) == 13) &ei, &e0, &e1, &e2, &e3, &e4, &e5, &a0, &a1, &a2, &a3,
buff, buff2) == 13)
{ {
#ifdef HAVE_BROKEN_RTC #ifdef HAVE_BROKEN_RTC
if (ei) if (ei)
...@@ -90,14 +92,14 @@ int lease_init(char *filename, char *domain, char *buff, ...@@ -90,14 +92,14 @@ int lease_init(char *filename, char *domain, char *buff,
memcpy(lease->hwaddr, hwaddr, ETHER_ADDR_LEN); memcpy(lease->hwaddr, hwaddr, ETHER_ADDR_LEN);
if (strcmp(buff, "*") != 0) if (strcmp(buff, "*") != 0)
lease_set_hostname(lease, buff, domain); lease_set_hostname(lease, buff, daemon->domain_suffix);
} }
dns_dirty = 1; dns_dirty = 1;
file_dirty = has_old; file_dirty = has_old;
new_lease = 0; new_lease = 0;
return fileno(lease_file); daemon->lease_fd = fileno(lease_file);
} }
void lease_update_from_configs(struct dhcp_config *dhcp_configs, char *domain) void lease_update_from_configs(struct dhcp_config *dhcp_configs, char *domain)
......
...@@ -14,16 +14,14 @@ ...@@ -14,16 +14,14 @@
#include "dnsmasq.h" #include "dnsmasq.h"
static struct irec *add_iface(struct irec *list, char *name, union mysockaddr *addr, static struct irec *add_iface(struct daemon *daemon, struct irec *list, char *name, union mysockaddr *addr)
struct iname *names, struct iname *addrs,
struct iname *except)
{ {
struct irec *iface; struct irec *iface;
struct iname *tmp; struct iname *tmp;
/* check blacklist */ /* check blacklist */
if (except) if (daemon->if_except)
for (tmp = except; tmp; tmp = tmp->next) for (tmp = daemon->if_except; tmp; tmp = tmp->next)
if (tmp->name && strcmp(tmp->name, name) == 0) if (tmp->name && strcmp(tmp->name, name) == 0)
{ {
/* record address of named interfaces, for TCP access control */ /* record address of named interfaces, for TCP access control */
...@@ -32,18 +30,18 @@ static struct irec *add_iface(struct irec *list, char *name, union mysockaddr *a ...@@ -32,18 +30,18 @@ static struct irec *add_iface(struct irec *list, char *name, union mysockaddr *a
} }
/* we may need to check the whitelist */ /* we may need to check the whitelist */
if (names || addrs) if (daemon->if_names || daemon->if_addrs)
{ {
int found = 0; int found = 0;
for (tmp = names; tmp; tmp = tmp->next) for (tmp = daemon->if_names; tmp; tmp = tmp->next)
if (tmp->name && (strcmp(tmp->name, name) == 0)) if (tmp->name && (strcmp(tmp->name, name) == 0))
{ {
tmp->addr = *addr; tmp->addr = *addr;
found = tmp->used = 1; found = tmp->used = 1;
} }
for (tmp = addrs; tmp; tmp = tmp->next) for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
if (sockaddr_isequal(&tmp->addr, addr)) if (sockaddr_isequal(&tmp->addr, addr))
found = tmp->used = 1; found = tmp->used = 1;
...@@ -67,10 +65,7 @@ static struct irec *add_iface(struct irec *list, char *name, union mysockaddr *a ...@@ -67,10 +65,7 @@ static struct irec *add_iface(struct irec *list, char *name, union mysockaddr *a
} }
struct irec *enumerate_interfaces(struct iname **names, struct irec *enumerate_interfaces(struct daemon *daemon)
struct iname **addrs,
struct iname *except,
int port)
{ {
struct irec *iface = NULL; struct irec *iface = NULL;
char *buf, *ptr; char *buf, *ptr;
...@@ -126,7 +121,7 @@ struct irec *enumerate_interfaces(struct iname **names, ...@@ -126,7 +121,7 @@ struct irec *enumerate_interfaces(struct iname **names,
if (ifr->ifr_addr.sa_family == AF_INET) if (ifr->ifr_addr.sa_family == AF_INET)
{ {
addr.in = *((struct sockaddr_in *) &ifr->ifr_addr); addr.in = *((struct sockaddr_in *) &ifr->ifr_addr);
addr.in.sin_port = htons(port); addr.in.sin_port = htons(daemon->port);
} }
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
else if (ifr->ifr_addr.sa_family == AF_INET6) else if (ifr->ifr_addr.sa_family == AF_INET6)
...@@ -136,7 +131,7 @@ struct irec *enumerate_interfaces(struct iname **names, ...@@ -136,7 +131,7 @@ struct irec *enumerate_interfaces(struct iname **names,
#else #else
addr.in6 = *((struct sockaddr_in6 *) &ifr->ifr_addr); addr.in6 = *((struct sockaddr_in6 *) &ifr->ifr_addr);
#endif #endif
addr.in6.sin6_port = htons(port); addr.in6.sin6_port = htons(daemon->port);
addr.in6.sin6_flowinfo = htonl(0); addr.in6.sin6_flowinfo = htonl(0);
} }
#endif #endif
...@@ -148,10 +143,10 @@ struct irec *enumerate_interfaces(struct iname **names, ...@@ -148,10 +143,10 @@ struct irec *enumerate_interfaces(struct iname **names,
/* If we are restricting the set of interfaces to use, make /* If we are restricting the set of interfaces to use, make
sure that loopback interfaces are in that set. */ sure that loopback interfaces are in that set. */
if (*names && (ifr->ifr_flags & IFF_LOOPBACK)) if (daemon->if_names && (ifr->ifr_flags & IFF_LOOPBACK))
{ {
struct iname *lo; struct iname *lo;
for (lo = *names; lo; lo = lo->next) for (lo = daemon->if_names; lo; lo = lo->next)
if (lo->name && strcmp(lo->name, ifr->ifr_name) == 0) if (lo->name && strcmp(lo->name, ifr->ifr_name) == 0)
{ {
lo->isloop = 1; lo->isloop = 1;
...@@ -162,12 +157,12 @@ struct irec *enumerate_interfaces(struct iname **names, ...@@ -162,12 +157,12 @@ struct irec *enumerate_interfaces(struct iname **names,
lo = safe_malloc(sizeof(struct iname)); lo = safe_malloc(sizeof(struct iname));
lo->name = safe_string_alloc(ifr->ifr_name); lo->name = safe_string_alloc(ifr->ifr_name);
lo->isloop = lo->used = 1; lo->isloop = lo->used = 1;
lo->next = *names; lo->next = daemon->if_names;
*names = lo; daemon->if_names = lo;
} }
} }
iface = add_iface(iface, ifr->ifr_name, &addr, *names, *addrs, except); iface = add_iface(daemon, iface, ifr->ifr_name, &addr);
#if defined(HAVE_LINUX_IPV6_PROC) && defined(HAVE_IPV6) #if defined(HAVE_LINUX_IPV6_PROC) && defined(HAVE_IPV6)
/* IPv6 addresses don't seem to work with SIOCGIFCONF. Barf */ /* IPv6 addresses don't seem to work with SIOCGIFCONF. Barf */
...@@ -198,7 +193,7 @@ struct irec *enumerate_interfaces(struct iname **names, ...@@ -198,7 +193,7 @@ struct irec *enumerate_interfaces(struct iname **names,
sscanf(addrstring+i+i, "%02x", &byte); sscanf(addrstring+i+i, "%02x", &byte);
addr6p[i] = byte; addr6p[i] = byte;
} }
addr6.in6.sin6_port = htons(port); addr6.in6.sin6_port = htons(daemon->port);
addr6.in6.sin6_flowinfo = htonl(0); addr6.in6.sin6_flowinfo = htonl(0);
addr6.in6.sin6_scope_id = htonl(scope); addr6.in6.sin6_scope_id = htonl(scope);
...@@ -211,7 +206,7 @@ struct irec *enumerate_interfaces(struct iname **names, ...@@ -211,7 +206,7 @@ struct irec *enumerate_interfaces(struct iname **names,
} }
if (found) if (found)
iface = add_iface(iface, ifr->ifr_name, &addr6, *names, *addrs, except); iface = add_iface(daemon, iface, ifr->ifr_name, &addr6);
} }
#endif /* LINUX */ #endif /* LINUX */
} }
...@@ -423,17 +418,19 @@ struct serverfd *allocate_sfd(union mysockaddr *addr, struct serverfd **sfds) ...@@ -423,17 +418,19 @@ struct serverfd *allocate_sfd(union mysockaddr *addr, struct serverfd **sfds)
return sfd; return sfd;
} }
struct server *check_servers(struct server *new, struct irec *interfaces, struct serverfd **sfds) void check_servers(struct daemon *daemon, struct irec *interfaces)
{ {
char addrbuff[ADDRSTRLEN]; char addrbuff[ADDRSTRLEN];
struct irec *iface; struct irec *iface;
struct server *tmp, *ret = NULL; struct server *new, *tmp, *ret = NULL;
int port = 0; int port = 0;
/* forward table rules reference servers, so have to blow them away */ /* forward table rules reference servers, so have to blow them away */
forward_init(0); forward_init(0);
for (;new; new = tmp) daemon->last_server = NULL;
for (new = daemon->servers; new; new = tmp)
{ {
tmp = new->next; tmp = new->next;
...@@ -465,7 +462,7 @@ struct server *check_servers(struct server *new, struct irec *interfaces, struct ...@@ -465,7 +462,7 @@ struct server *check_servers(struct server *new, struct irec *interfaces, struct
} }
/* Do we need a socket set? */ /* Do we need a socket set? */
if (!new->sfd && !(new->sfd = allocate_sfd(&new->source_addr, sfds))) if (!new->sfd && !(new->sfd = allocate_sfd(&new->source_addr, &daemon->sfds)))
{ {
syslog(LOG_WARNING, syslog(LOG_WARNING,
"ignoring nameserver %s - cannot make/bind socket: %m", addrbuff); "ignoring nameserver %s - cannot make/bind socket: %m", addrbuff);
...@@ -495,15 +492,16 @@ struct server *check_servers(struct server *new, struct irec *interfaces, struct ...@@ -495,15 +492,16 @@ struct server *check_servers(struct server *new, struct irec *interfaces, struct
syslog(LOG_INFO, "using nameserver %s#%d", addrbuff, port); syslog(LOG_INFO, "using nameserver %s#%d", addrbuff, port);
} }
return ret; daemon->servers = ret;
} }
struct server *reload_servers(char *fname, char *buff, struct server *serv, int query_port) void reload_servers(char *fname, struct daemon *daemon)
{ {
FILE *f; FILE *f;
char *line; char *line;
struct server *old_servers = NULL; struct server *old_servers = NULL;
struct server *new_servers = NULL; struct server *new_servers = NULL;
struct server *serv = daemon->servers;
/* move old servers to free list - we can reuse the memory /* move old servers to free list - we can reuse the memory
and not risk malloc if there are the same or fewer new servers. and not risk malloc if there are the same or fewer new servers.
...@@ -533,7 +531,7 @@ struct server *reload_servers(char *fname, char *buff, struct server *serv, int ...@@ -533,7 +531,7 @@ struct server *reload_servers(char *fname, char *buff, struct server *serv, int
else else
{ {
syslog(LOG_INFO, "reading %s", fname); syslog(LOG_INFO, "reading %s", fname);
while ((line = fgets(buff, MAXDNAME, f))) while ((line = fgets(daemon->namebuff, MAXDNAME, f)))
{ {
union mysockaddr addr, source_addr; union mysockaddr addr, source_addr;
char *token = strtok(line, " \t\n\r"); char *token = strtok(line, " \t\n\r");
...@@ -556,7 +554,7 @@ struct server *reload_servers(char *fname, char *buff, struct server *serv, int ...@@ -556,7 +554,7 @@ struct server *reload_servers(char *fname, char *buff, struct server *serv, int
source_addr.in.sin_family = addr.in.sin_family = AF_INET; source_addr.in.sin_family = addr.in.sin_family = AF_INET;
addr.in.sin_port = htons(NAMESERVER_PORT); addr.in.sin_port = htons(NAMESERVER_PORT);
source_addr.in.sin_addr.s_addr = INADDR_ANY; source_addr.in.sin_addr.s_addr = INADDR_ANY;
source_addr.in.sin_port = htons(query_port); source_addr.in.sin_port = htons(daemon->query_port);
} }
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
else if (inet_pton(AF_INET6, token, &addr.in6.sin6_addr)) else if (inet_pton(AF_INET6, token, &addr.in6.sin6_addr))
...@@ -568,7 +566,7 @@ struct server *reload_servers(char *fname, char *buff, struct server *serv, int ...@@ -568,7 +566,7 @@ struct server *reload_servers(char *fname, char *buff, struct server *serv, int
addr.in6.sin6_port = htons(NAMESERVER_PORT); addr.in6.sin6_port = htons(NAMESERVER_PORT);
source_addr.in6.sin6_flowinfo = addr.in6.sin6_flowinfo = htonl(0); source_addr.in6.sin6_flowinfo = addr.in6.sin6_flowinfo = htonl(0);
source_addr.in6.sin6_addr = in6addr_any; source_addr.in6.sin6_addr = in6addr_any;
source_addr.in6.sin6_port = htons(query_port); source_addr.in6.sin6_port = htons(daemon->query_port);
} }
#endif /* IPV6 */ #endif /* IPV6 */
else else
...@@ -604,7 +602,7 @@ struct server *reload_servers(char *fname, char *buff, struct server *serv, int ...@@ -604,7 +602,7 @@ struct server *reload_servers(char *fname, char *buff, struct server *serv, int
old_servers = tmp; old_servers = tmp;
} }
return new_servers; daemon->servers = new_servers;
} }
......
This diff is collapsed.
...@@ -340,7 +340,7 @@ unsigned char *find_pseudoheader(HEADER *header, unsigned int plen) ...@@ -340,7 +340,7 @@ unsigned char *find_pseudoheader(HEADER *header, unsigned int plen)
GETSHORT(rdlen, ansp); GETSHORT(rdlen, ansp);
if ((unsigned int)(ansp + rdlen - (unsigned char *)header) > plen) if ((unsigned int)(ansp + rdlen - (unsigned char *)header) > plen)
return NULL; return NULL;
if (type == ns_t_opt) if (type == T_OPT)
return save; return save;
ansp += rdlen; ansp += rdlen;
} }
...@@ -788,10 +788,9 @@ int check_for_bogus_wildcard(HEADER *header, unsigned int qlen, char *name, ...@@ -788,10 +788,9 @@ 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 */ /* 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, struct mx_record *mxnames, int answer_request(HEADER *header, char *limit, unsigned int qlen, struct daemon *daemon, time_t now)
char *mxtarget, unsigned int options, time_t now,
unsigned long local_ttl, char *name, unsigned short edns_pcktsz)
{ {
char *name = daemon->namebuff;
unsigned char *p, *ansp, *pheader; unsigned char *p, *ansp, *pheader;
int qtype, qclass, is_arpa; int qtype, qclass, is_arpa;
struct all_addr addr; struct all_addr addr;
...@@ -827,8 +826,8 @@ int answer_request(HEADER *header, char *limit, unsigned int qlen, struct mx_rec ...@@ -827,8 +826,8 @@ int answer_request(HEADER *header, char *limit, unsigned int qlen, struct mx_rec
than we allow, trim it so that we don't get an overlarge than we allow, trim it so that we don't get an overlarge
response from upstream */ response from upstream */
if (udpsz > edns_pcktsz) if (udpsz > daemon->edns_pktsz)
PUTSHORT(edns_pcktsz, psave); PUTSHORT(daemon->edns_pktsz, psave);
dryrun = 1; dryrun = 1;
} }
...@@ -889,7 +888,7 @@ int answer_request(HEADER *header, char *limit, unsigned int qlen, struct mx_rec ...@@ -889,7 +888,7 @@ int answer_request(HEADER *header, char *limit, unsigned int qlen, struct mx_rec
} }
else if (qclass == C_IN) else if (qclass == C_IN)
{ {
if ((options & OPT_FILTER) && if ((daemon->options & OPT_FILTER) &&
(qtype == T_SOA || qtype == T_SRV || (qtype == T_ANY && strchr(name, '_')))) (qtype == T_SOA || qtype == T_SRV || (qtype == T_ANY && strchr(name, '_'))))
{ {
ans = 1; ans = 1;
...@@ -901,7 +900,7 @@ int answer_request(HEADER *header, char *limit, unsigned int qlen, struct mx_rec ...@@ -901,7 +900,7 @@ int answer_request(HEADER *header, char *limit, unsigned int qlen, struct mx_rec
{ {
if (!(crecp = cache_find_by_addr(NULL, &addr, now, is_arpa))) if (!(crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
{ {
if (is_arpa == F_IPV4 && (options & OPT_BOGUSPRIV) && private_net(&addr)) if (is_arpa == F_IPV4 && (daemon->options & OPT_BOGUSPRIV) && private_net(&addr))
{ {
/* if not in cache, enabled and private IPV4 address, return NXDOMAIN */ /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
ans = 1; ans = 1;
...@@ -938,7 +937,7 @@ int answer_request(HEADER *header, char *limit, unsigned int qlen, struct mx_rec ...@@ -938,7 +937,7 @@ int answer_request(HEADER *header, char *limit, unsigned int qlen, struct mx_rec
/* Return 0 ttl for DHCP entries, which might change /* Return 0 ttl for DHCP entries, which might change
before the lease expires. */ before the lease expires. */
if (crecp->flags & (F_IMMORTAL | F_DHCP)) if (crecp->flags & (F_IMMORTAL | F_DHCP))
ttl = local_ttl; ttl = daemon->local_ttl;
else else
ttl = crecp->ttd - now; ttl = crecp->ttd - now;
...@@ -1004,7 +1003,7 @@ int answer_request(HEADER *header, char *limit, unsigned int qlen, struct mx_rec ...@@ -1004,7 +1003,7 @@ int answer_request(HEADER *header, char *limit, unsigned int qlen, struct mx_rec
unsigned long ttl; unsigned long ttl;
if (crecp->flags & (F_IMMORTAL | F_DHCP)) if (crecp->flags & (F_IMMORTAL | F_DHCP))
ttl = local_ttl; ttl = daemon->local_ttl;
else else
ttl = crecp->ttd - now; ttl = crecp->ttd - now;
...@@ -1033,7 +1032,7 @@ int answer_request(HEADER *header, char *limit, unsigned int qlen, struct mx_rec ...@@ -1033,7 +1032,7 @@ int answer_request(HEADER *header, char *limit, unsigned int qlen, struct mx_rec
if (qtype == T_MX || qtype == T_ANY) if (qtype == T_MX || qtype == T_ANY)
{ {
struct mx_record *mx; struct mx_record *mx;
for (mx = mxnames; mx; mx = mx->next) for (mx = daemon->mxnames; mx; mx = mx->next)
if (hostname_isequal(name, mx->mxname)) if (hostname_isequal(name, mx->mxname))
break; break;
if (mx) if (mx)
...@@ -1041,19 +1040,19 @@ int answer_request(HEADER *header, char *limit, unsigned int qlen, struct mx_rec ...@@ -1041,19 +1040,19 @@ int answer_request(HEADER *header, char *limit, unsigned int qlen, struct mx_rec
ans = 1; ans = 1;
if (!dryrun) if (!dryrun)
{ {
ansp = add_text_record(nameoffset, ansp, local_ttl, 1, T_MX, ansp = add_text_record(nameoffset, ansp, daemon->local_ttl, 1, T_MX,
mx->mxtarget ? mx->mxtarget : mxtarget); mx->mxtarget ? mx->mxtarget : daemon->mxtarget);
anscount++; anscount++;
} }
} }
else if ((options & (OPT_SELFMX | OPT_LOCALMX)) && else if ((daemon->options & (OPT_SELFMX | OPT_LOCALMX)) &&
cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP)) cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP))
{ {
ans = 1; ans = 1;
if (!dryrun) if (!dryrun)
{ {
ansp = add_text_record(nameoffset, ansp, local_ttl, 1, T_MX, ansp = add_text_record(nameoffset, ansp, daemon->local_ttl, 1, T_MX,
(options & OPT_SELFMX) ? name : mxtarget); (daemon->options & OPT_SELFMX) ? name : daemon->mxtarget);
anscount++; anscount++;
} }
} }
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment