]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/dnsmasq/001-Add_TTL_parameter_to_--host-record_and_--cname.patch
Merge branch 'bird' into next
[ipfire-2.x.git] / src / patches / dnsmasq / 001-Add_TTL_parameter_to_--host-record_and_--cname.patch
1 From df3d54f776a3c9b60735b45c0b7fd88b66a2d5c4 Mon Sep 17 00:00:00 2001
2 From: Simon Kelley <simon@thekelleys.org.uk>
3 Date: Wed, 24 Feb 2016 21:03:38 +0000
4 Subject: [PATCH] Add TTL parameter to --host-record and --cname.
5
6 ---
7 man/dnsmasq.8 | 12 ++++++++++--
8 src/cache.c | 7 +++++++
9 src/dnsmasq.h | 2 ++
10 src/option.c | 46 ++++++++++++++++++++++++++++++++++++++--------
11 src/rfc1035.c | 6 +++++-
12 5 files changed, 62 insertions(+), 11 deletions(-)
13
14 diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
15 index b782eaf..7bc1394 100644
16 --- a/man/dnsmasq.8
17 +++ b/man/dnsmasq.8
18 @@ -529,7 +529,7 @@ zone files: the port, weight and priority numbers are in a different
19 order. More than one SRV record for a given service/domain is allowed,
20 all that match are returned.
21 .TP
22 -.B --host-record=<name>[,<name>....],[<IPv4-address>],[<IPv6-address>]
23 +.B --host-record=<name>[,<name>....],[<IPv4-address>],[<IPv6-address>][,<TTL>]
24 Add A, AAAA and PTR records to the DNS. This adds one or more names to
25 the DNS with associated IPv4 (A) and IPv6 (AAAA) records. A name may
26 appear in more than one
27 @@ -546,6 +546,10 @@ is in effect. Short and long names may appear in the same
28 .B host-record,
29 eg.
30 .B --host-record=laptop,laptop.thekelleys.org,192.168.0.1,1234::100
31 +
32 +If the time-to-live is given, it overrides the default, which is zero
33 +or the value of --local-ttl. The value is a positive integer and gives
34 +the time-to-live in seconds.
35 .TP
36 .B \-Y, --txt-record=<name>[[,<text>],<text>]
37 Return a TXT DNS record. The value of TXT record is a set of strings,
38 @@ -559,7 +563,7 @@ Return a PTR DNS record.
39 .B --naptr-record=<name>,<order>,<preference>,<flags>,<service>,<regexp>[,<replacement>]
40 Return an NAPTR DNS record, as specified in RFC3403.
41 .TP
42 -.B --cname=<cname>,<target>
43 +.B --cname=<cname>,<target>[,<TTL>]
44 Return a CNAME record which indicates that <cname> is really
45 <target>. There are significant limitations on the target; it must be a
46 DNS name which is known to dnsmasq from /etc/hosts (or additional
47 @@ -568,6 +572,10 @@ hosts files), from DHCP, from --interface-name or from another
48 If the target does not satisfy this
49 criteria, the whole cname is ignored. The cname must be unique, but it
50 is permissable to have more than one cname pointing to the same target.
51 +
52 +If the time-to-live is given, it overrides the default, which is zero
53 +or the value of -local-ttl. The value is a positive integer and gives
54 +the time-to-live in seconds.
55 .TP
56 .B --dns-rr=<name>,<RR-number>,[<hex data>]
57 Return an arbitrary DNS Resource Record. The number is the type of the
58 diff --git a/src/cache.c b/src/cache.c
59 index a9eaa65..4ecd535 100644
60 --- a/src/cache.c
61 +++ b/src/cache.c
62 @@ -778,6 +778,7 @@ static void add_hosts_cname(struct crec *target)
63 (crec = whine_malloc(sizeof(struct crec))))
64 {
65 crec->flags = F_FORWARD | F_IMMORTAL | F_NAMEP | F_CONFIG | F_CNAME;
66 + crec->ttd = a->ttl;
67 crec->name.namep = a->alias;
68 crec->addr.cname.target.cache = target;
69 crec->addr.cname.uid = target->uid;
70 @@ -981,6 +982,7 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr
71 strcat(cache->name.sname, ".");
72 strcat(cache->name.sname, domain_suffix);
73 cache->flags = flags;
74 + cache->ttd = daemon->local_ttl;
75 add_hosts_entry(cache, &addr, addrlen, index, rhash, hashsz);
76 name_count++;
77 }
78 @@ -988,6 +990,7 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr
79 {
80 strcpy(cache->name.sname, canon);
81 cache->flags = flags;
82 + cache->ttd = daemon->local_ttl;
83 add_hosts_entry(cache, &addr, addrlen, index, rhash, hashsz);
84 name_count++;
85 }
86 @@ -1057,6 +1060,7 @@ void cache_reload(void)
87 ((cache = whine_malloc(sizeof(struct crec)))))
88 {
89 cache->flags = F_FORWARD | F_NAMEP | F_CNAME | F_IMMORTAL | F_CONFIG;
90 + cache->ttd = a->ttl;
91 cache->name.namep = a->alias;
92 cache->addr.cname.target.int_name = intr;
93 cache->addr.cname.uid = SRC_INTERFACE;
94 @@ -1071,6 +1075,7 @@ void cache_reload(void)
95 (cache->addr.ds.keydata = blockdata_alloc(ds->digest, ds->digestlen)))
96 {
97 cache->flags = F_FORWARD | F_IMMORTAL | F_DS | F_CONFIG | F_NAMEP;
98 + cache->ttd = daemon->local_ttl;
99 cache->name.namep = ds->name;
100 cache->addr.ds.keylen = ds->digestlen;
101 cache->addr.ds.algo = ds->algo;
102 @@ -1095,6 +1100,7 @@ void cache_reload(void)
103 (cache = whine_malloc(sizeof(struct crec))))
104 {
105 cache->name.namep = nl->name;
106 + cache->ttd = hr->ttl;
107 cache->flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4 | F_NAMEP | F_CONFIG;
108 add_hosts_entry(cache, (struct all_addr *)&hr->addr, INADDRSZ, SRC_CONFIG, (struct crec **)daemon->packet, revhashsz);
109 }
110 @@ -1103,6 +1109,7 @@ void cache_reload(void)
111 (cache = whine_malloc(sizeof(struct crec))))
112 {
113 cache->name.namep = nl->name;
114 + cache->ttd = hr->ttl;
115 cache->flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV6 | F_NAMEP | F_CONFIG;
116 add_hosts_entry(cache, (struct all_addr *)&hr->addr6, IN6ADDRSZ, SRC_CONFIG, (struct crec **)daemon->packet, revhashsz);
117 }
118 diff --git a/src/dnsmasq.h b/src/dnsmasq.h
119 index 6d1c5ae..6344df5 100644
120 --- a/src/dnsmasq.h
121 +++ b/src/dnsmasq.h
122 @@ -308,6 +308,7 @@ struct ptr_record {
123 };
124
125 struct cname {
126 + int ttl;
127 char *alias, *target;
128 struct cname *next;
129 };
130 @@ -344,6 +345,7 @@ struct auth_zone {
131
132
133 struct host_record {
134 + int ttl;
135 struct name_list {
136 char *name;
137 struct name_list *next;
138 diff --git a/src/option.c b/src/option.c
139 index c98bdc9..7c5e6bc 100644
140 --- a/src/option.c
141 +++ b/src/option.c
142 @@ -448,20 +448,20 @@ static struct {
143 { LOPT_GEN_NAMES, ARG_DUP, "[=tag:<tag>]", gettext_noop("Generate hostnames based on MAC address for nameless clients."), NULL},
144 { LOPT_PROXY, ARG_DUP, "[=<ipaddr>]...", gettext_noop("Use these DHCP relays as full proxies."), NULL },
145 { LOPT_RELAY, ARG_DUP, "<local-addr>,<server>[,<interface>]", gettext_noop("Relay DHCP requests to a remote server"), NULL},
146 - { LOPT_CNAME, ARG_DUP, "<alias>,<target>", gettext_noop("Specify alias name for LOCAL DNS name."), NULL },
147 + { LOPT_CNAME, ARG_DUP, "<alias>,<target>[,<ttl>]", gettext_noop("Specify alias name for LOCAL DNS name."), NULL },
148 { LOPT_PXE_PROMT, ARG_DUP, "<prompt>,[<timeout>]", gettext_noop("Prompt to send to PXE clients."), NULL },
149 { LOPT_PXE_SERV, ARG_DUP, "<service>", gettext_noop("Boot service for PXE menu."), NULL },
150 { LOPT_TEST, 0, NULL, gettext_noop("Check configuration syntax."), NULL },
151 { LOPT_ADD_MAC, ARG_DUP, "[=base64|text]", gettext_noop("Add requestor's MAC address to forwarded DNS queries."), NULL },
152 { LOPT_ADD_SBNET, ARG_ONE, "<v4 pref>[,<v6 pref>]", gettext_noop("Add specified IP subnet to forwarded DNS queries."), NULL },
153 - { LOPT_CPE_ID, ARG_ONE, "<text>", gettext_noop("Add client identification to forwarded DNS queries."), NULL },
154 + { LOPT_CPE_ID, ARG_ONE, "<text>", gettext_noop("Add client identification to forwarded DNS queries."), NULL },
155 { LOPT_DNSSEC, OPT_DNSSEC_PROXY, NULL, gettext_noop("Proxy DNSSEC validation results from upstream nameservers."), NULL },
156 { LOPT_INCR_ADDR, OPT_CONSEC_ADDR, NULL, gettext_noop("Attempt to allocate sequential IP addresses to DHCP clients."), NULL },
157 { LOPT_CONNTRACK, OPT_CONNTRACK, NULL, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL },
158 { LOPT_FQDN, OPT_FQDN_UPDATE, NULL, gettext_noop("Allow DHCP clients to do their own DDNS updates."), NULL },
159 { LOPT_RA, OPT_RA, NULL, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL },
160 { LOPT_DUID, ARG_ONE, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL },
161 - { LOPT_HOST_REC, ARG_DUP, "<name>,<address>", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL },
162 + { LOPT_HOST_REC, ARG_DUP, "<name>,<address>[,<ttl>]", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL },
163 { LOPT_RR, ARG_DUP, "<name>,<RR-number>,[<data>]", gettext_noop("Specify arbitrary DNS resource record"), NULL },
164 { LOPT_CLVERBIND, OPT_CLEVERBIND, NULL, gettext_noop("Bind to interfaces in use - check for new interfaces"), NULL },
165 { LOPT_AUTHSERV, ARG_ONE, "<NS>,<interface>", gettext_noop("Export local names to global DNS"), NULL },
166 @@ -3692,12 +3692,15 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
167 case LOPT_CNAME: /* --cname */
168 {
169 struct cname *new;
170 - char *alias;
171 - char *target;
172 + char *alias, *target, *ttls;
173 + int ttl = -1;
174
175 if (!(comma = split(arg)))
176 ret_err(gen_err);
177
178 + if ((ttls = split(comma)) && !atoi_check(ttls, &ttl))
179 + ret_err(_("bad TTL"));
180 +
181 alias = canonicalise_opt(arg);
182 target = canonicalise_opt(comma);
183
184 @@ -3713,6 +3716,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
185 daemon->cnames = new;
186 new->alias = alias;
187 new->target = target;
188 + new->ttl = ttl;
189 }
190
191 break;
192 @@ -3913,14 +3917,22 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
193 {
194 struct host_record *new = opt_malloc(sizeof(struct host_record));
195 memset(new, 0, sizeof(struct host_record));
196 -
197 + new->ttl = -1;
198 +
199 if (!arg || !(comma = split(arg)))
200 ret_err(_("Bad host-record"));
201
202 while (arg)
203 {
204 struct all_addr addr;
205 - if (inet_pton(AF_INET, arg, &addr))
206 + char *dig;
207 +
208 + for (dig = arg; *dig != 0; dig++)
209 + if (*dig < '0' || *dig > '9')
210 + break;
211 + if (*dig == 0)
212 + new->ttl = atoi(arg);
213 + else if (inet_pton(AF_INET, arg, &addr))
214 new->addr = addr.addr.addr4;
215 #ifdef HAVE_IPV6
216 else if (inet_pton(AF_INET6, arg, &addr))
217 @@ -4601,7 +4613,25 @@ void read_opts(int argc, char **argv, char *compile_opts)
218 }
219 }
220 }
221 -
222 +
223 + if (daemon->host_records)
224 + {
225 + struct host_record *hr;
226 +
227 + for (hr = daemon->host_records; hr; hr = hr->next)
228 + if (hr->ttl == -1)
229 + hr->ttl = daemon->local_ttl;
230 + }
231 +
232 + if (daemon->cnames)
233 + {
234 + struct cname *cn;
235 +
236 + for (cn = daemon->cnames; cn; cn = cn->next)
237 + if (cn->ttl == -1)
238 + cn->ttl = daemon->local_ttl;
239 + }
240 +
241 if (daemon->if_addrs)
242 {
243 struct iname *tmp;
244 diff --git a/src/rfc1035.c b/src/rfc1035.c
245 index 9c0ddb5..3535a71 100644
246 --- a/src/rfc1035.c
247 +++ b/src/rfc1035.c
248 @@ -1169,9 +1169,13 @@ static unsigned long crec_ttl(struct crec *crecp, time_t now)
249 /* Return 0 ttl for DHCP entries, which might change
250 before the lease expires. */
251
252 - if (crecp->flags & (F_IMMORTAL | F_DHCP))
253 + if (crecp->flags & F_DHCP)
254 return daemon->local_ttl;
255
256 + /* Immortal entries other than DHCP are local, and hold TTL in TTD field. */
257 + if (crecp->flags & F_IMMORTAL)
258 + return crecp->ttd;
259 +
260 /* Return the Max TTL value if it is lower then the actual TTL */
261 if (daemon->max_ttl == 0 || ((unsigned)(crecp->ttd - now) < daemon->max_ttl))
262 return crecp->ttd - now;
263 --
264 1.7.10.4
265