]>
Commit | Line | Data |
---|---|---|
3b9815eb MF |
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 |