diff --git a/java/google/registry/config/RegistryConfig.java b/java/google/registry/config/RegistryConfig.java index e76dffcb4..54bc85b1d 100644 --- a/java/google/registry/config/RegistryConfig.java +++ b/java/google/registry/config/RegistryConfig.java @@ -286,13 +286,35 @@ public final class RegistryConfig { } /** - * Returns the default time to live for DNS records. + * Returns the default time to live for DNS A and AAAA records. * * @see google.registry.dns.writer.clouddns.CloudDnsWriter */ @Provides - @Config("dnsDefaultTtl") - public static Duration provideDnsDefaultTtl() { + @Config("dnsDefaultATtl") + public static Duration provideDnsDefaultATtl() { + return Duration.standardSeconds(180); + } + + /** + * Returns the default time to live for DNS NS records. + * + * @see google.registry.dns.writer.clouddns.CloudDnsWriter + */ + @Provides + @Config("dnsDefaultNsTtl") + public static Duration provideDnsDefaultNsTtl() { + return Duration.standardSeconds(180); + } + + /** + * Returns the default time to live for DNS DS records. + * + * @see google.registry.dns.writer.clouddns.CloudDnsWriter + */ + @Provides + @Config("dnsDefaultDsTtl") + public static Duration provideDnsDefaultDsTtl() { return Duration.standardSeconds(180); } diff --git a/java/google/registry/dns/writer/clouddns/CloudDnsWriter.java b/java/google/registry/dns/writer/clouddns/CloudDnsWriter.java index 8bc1c1d2e..1182de258 100644 --- a/java/google/registry/dns/writer/clouddns/CloudDnsWriter.java +++ b/java/google/registry/dns/writer/clouddns/CloudDnsWriter.java @@ -75,7 +75,9 @@ public class CloudDnsWriter implements DnsWriter { // TODO(shikhman): This uses @Named("transientFailureRetries") which may not be tuned for this // application. private final Retrier retrier; - private final Duration defaultTtl; + private final Duration defaultATtl; + private final Duration defaultNsTtl; + private final Duration defaultDsTtl; private final String projectId; private final String zoneName; private final Dns dnsConnection; @@ -87,14 +89,18 @@ public class CloudDnsWriter implements DnsWriter { Dns dnsConnection, @Config("projectId") String projectId, @DnsWriterZone String zoneName, - @Config("dnsDefaultTtl") Duration defaultTtl, + @Config("dnsDefaultATtl") Duration defaultATtl, + @Config("dnsDefaultNsTtl") Duration defaultNsTtl, + @Config("dnsDefaultDsTtl") Duration defaultDsTtl, @Named("cloudDns") RateLimiter rateLimiter, Clock clock, Retrier retrier) { this.dnsConnection = dnsConnection; this.projectId = projectId; this.zoneName = zoneName; - this.defaultTtl = defaultTtl; + this.defaultATtl = defaultATtl; + this.defaultNsTtl = defaultNsTtl; + this.defaultDsTtl = defaultDsTtl; this.rateLimiter = rateLimiter; this.clock = clock; this.retrier = retrier; @@ -132,7 +138,7 @@ public class CloudDnsWriter implements DnsWriter { domainRecords.add( new ResourceRecordSet() .setName(absoluteDomainName) - .setTtl((int) defaultTtl.getStandardSeconds()) + .setTtl((int) defaultDsTtl.getStandardSeconds()) .setType("DS") .setKind("dns#resourceRecordSet") .setRrdatas(ImmutableList.copyOf(dsRrData))); @@ -157,7 +163,7 @@ public class CloudDnsWriter implements DnsWriter { domainRecords.add( new ResourceRecordSet() .setName(absoluteDomainName) - .setTtl((int) defaultTtl.getStandardSeconds()) + .setTtl((int) defaultNsTtl.getStandardSeconds()) .setType("NS") .setKind("dns#resourceRecordSet") .setRrdatas(ImmutableList.copyOf(nsRrData))); @@ -204,7 +210,7 @@ public class CloudDnsWriter implements DnsWriter { domainRecords.add( new ResourceRecordSet() .setName(absoluteHostName) - .setTtl((int) defaultTtl.getStandardSeconds()) + .setTtl((int) defaultATtl.getStandardSeconds()) .setType("A") .setKind("dns#resourceRecordSet") .setRrdatas(ImmutableList.copyOf(aRrData))); @@ -214,7 +220,7 @@ public class CloudDnsWriter implements DnsWriter { domainRecords.add( new ResourceRecordSet() .setName(absoluteHostName) - .setTtl((int) defaultTtl.getStandardSeconds()) + .setTtl((int) defaultATtl.getStandardSeconds()) .setType("AAAA") .setKind("dns#resourceRecordSet") .setRrdatas(ImmutableList.copyOf(aaaaRrData))); diff --git a/java/google/registry/dns/writer/dnsupdate/DnsUpdateConfigModule.java b/java/google/registry/dns/writer/dnsupdate/DnsUpdateConfigModule.java index fd36dcb8d..c08d7da24 100644 --- a/java/google/registry/dns/writer/dnsupdate/DnsUpdateConfigModule.java +++ b/java/google/registry/dns/writer/dnsupdate/DnsUpdateConfigModule.java @@ -41,13 +41,4 @@ public class DnsUpdateConfigModule { public static Duration provideDnsUpdateTimeout() { return Duration.standardSeconds(30); } - - /** - * The DNS time-to-live (TTL) for resource records created by the registry. - */ - @Provides - @Config("dnsUpdateTimeToLive") - public static Duration provideDnsUpdateTimeToLive() { - return Duration.standardHours(2); - } } diff --git a/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriter.java b/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriter.java index 8925f7a3f..61f174ed6 100644 --- a/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriter.java +++ b/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriter.java @@ -81,7 +81,9 @@ public class DnsUpdateWriter implements DnsWriter { */ public static final String NAME = "DnsUpdateWriter"; - private final Duration dnsTimeToLive; + private final Duration dnsDefaultATtl; + private final Duration dnsDefaultNsTtl; + private final Duration dnsDefaultDsTtl; private final DnsMessageTransport transport; private final Clock clock; @@ -94,10 +96,14 @@ public class DnsUpdateWriter implements DnsWriter { */ @Inject public DnsUpdateWriter( - @Config("dnsUpdateTimeToLive") Duration dnsTimeToLive, + @Config("dnsDefaultATtl") Duration dnsDefaultATtl, + @Config("dnsDefaultNsTtl") Duration dnsDefaultNsTtl, + @Config("dnsDefaultDsTtl") Duration dnsDefaultDsTtl, DnsMessageTransport transport, Clock clock) { - this.dnsTimeToLive = dnsTimeToLive; + this.dnsDefaultATtl = dnsDefaultATtl; + this.dnsDefaultNsTtl = dnsDefaultNsTtl; + this.dnsDefaultDsTtl = dnsDefaultDsTtl; this.transport = transport; this.clock = clock; } @@ -175,7 +181,7 @@ public class DnsUpdateWriter implements DnsWriter { new DSRecord( toAbsoluteName(domain.getFullyQualifiedDomainName()), DClass.IN, - dnsTimeToLive.getStandardSeconds(), + dnsDefaultDsTtl.getStandardSeconds(), signerData.getKeyTag(), signerData.getAlgorithm(), signerData.getDigestType(), @@ -215,7 +221,7 @@ public class DnsUpdateWriter implements DnsWriter { new NSRecord( toAbsoluteName(domain.getFullyQualifiedDomainName()), DClass.IN, - dnsTimeToLive.getStandardSeconds(), + dnsDefaultNsTtl.getStandardSeconds(), toAbsoluteName(hostName)); nameServerSet.addRR(record); } @@ -230,7 +236,7 @@ public class DnsUpdateWriter implements DnsWriter { new ARecord( toAbsoluteName(host.getFullyQualifiedHostName()), DClass.IN, - dnsTimeToLive.getStandardSeconds(), + dnsDefaultATtl.getStandardSeconds(), address); addressSet.addRR(record); } @@ -246,7 +252,7 @@ public class DnsUpdateWriter implements DnsWriter { new AAAARecord( toAbsoluteName(host.getFullyQualifiedHostName()), DClass.IN, - dnsTimeToLive.getStandardSeconds(), + dnsDefaultATtl.getStandardSeconds(), address); addressSet.addRR(record); } diff --git a/java/google/registry/tools/server/GenerateZoneFilesAction.java b/java/google/registry/tools/server/GenerateZoneFilesAction.java index 69d402ac2..930ed2c35 100644 --- a/java/google/registry/tools/server/GenerateZoneFilesAction.java +++ b/java/google/registry/tools/server/GenerateZoneFilesAction.java @@ -97,21 +97,14 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA /** Format for A and AAAA records. */ private static final String A_FORMAT = "%s\t%d\tIN\t%s\t%s\n"; - // TODO(b/20454352): Overhaul TTL configuration mechanism. - /** The time to live for exported NS record, in seconds. */ - private static final int TTL_NS = 180; - - /** The time to live for exported DS record, in seconds. */ - private static final int TTL_DS = 86400; - - /** The time to live for exported A/AAAA record, in seconds. */ - private static final int TTL_A = 3600; - @Inject MapreduceRunner mrRunner; @Inject JsonActionRunner jsonActionRunner; @Inject @Config("zoneFilesBucket") String bucket; @Inject @Config("gcsBufferSize") int gcsBufferSize; @Inject @Config("commitLogDatastoreRetention") Duration datastoreRetention; + @Inject @Config("dnsDefaultATtl") Duration dnsDefaultATtl; + @Inject @Config("dnsDefaultNsTtl") Duration dnsDefaultNsTtl; + @Inject @Config("dnsDefaultDsTtl") Duration dnsDefaultDsTtl; @Inject Clock clock; @Inject GenerateZoneFilesAction() {} @@ -145,7 +138,8 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA .setModuleName("tools") .setDefaultReduceShards(tlds.size()) .runMapreduce( - new GenerateBindFileMapper(tlds, exportTime), + new GenerateBindFileMapper( + tlds, exportTime, dnsDefaultATtl, dnsDefaultNsTtl, dnsDefaultDsTtl), new GenerateBindFileReducer(bucket, exportTime, gcsBufferSize), ImmutableList.of( new NullInput(), @@ -173,10 +167,21 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA private final ImmutableSet tlds; private final DateTime exportTime; + private final Duration dnsDefaultATtl; + private final Duration dnsDefaultNsTtl; + private final Duration dnsDefaultDsTtl; - GenerateBindFileMapper(ImmutableSet tlds, DateTime exportTime) { + GenerateBindFileMapper( + ImmutableSet tlds, + DateTime exportTime, + Duration dnsDefaultATtl, + Duration dnsDefaultNsTtl, + Duration dnsDefaultDsTtl) { this.tlds = tlds; this.exportTime = exportTime; + this.dnsDefaultATtl = dnsDefaultATtl; + this.dnsDefaultNsTtl = dnsDefaultNsTtl; + this.dnsDefaultDsTtl = dnsDefaultDsTtl; } @Override @@ -198,7 +203,7 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA domain = loadAtPointInTime(domain, exportTime).now(); // A null means the domain was deleted (or not created) at this time. if (domain != null && domain.shouldPublishToDns()) { - String stanza = domainStanza(domain, exportTime); + String stanza = domainStanza(domain, exportTime, dnsDefaultNsTtl, dnsDefaultDsTtl); if (!stanza.isEmpty()) { emit(domain.getTld(), stanza); getContext().incrementCounter(domain.getTld() + " domains"); @@ -214,7 +219,7 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA String fullyQualifiedHostName = host.getFullyQualifiedHostName(); for (String tld : tlds) { if (fullyQualifiedHostName.endsWith("." + tld)) { - String stanza = hostStanza(host); + String stanza = hostStanza(host, dnsDefaultATtl); if (!stanza.isEmpty()) { emit(tld, stanza); getContext().incrementCounter(tld + " hosts"); @@ -272,13 +277,17 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA * foo.tld 86400 IN DS 1 2 3 000102 * } */ - private static String domainStanza(DomainResource domain, DateTime exportTime) { + private static String domainStanza( + DomainResource domain, + DateTime exportTime, + Duration dnsDefaultNsTtl, + Duration dnsDefaultDsTtl) { StringBuilder result = new StringBuilder(); for (HostResource nameserver : ofy().load().keys(domain.getNameservers()).values()) { result.append(String.format( NS_FORMAT, domain.getFullyQualifiedDomainName(), - TTL_NS, + dnsDefaultNsTtl.getStandardSeconds(), // Load the nameservers at the export time in case they've been renamed or deleted. loadAtPointInTime(nameserver, exportTime).now().getFullyQualifiedHostName())); } @@ -286,7 +295,7 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA result.append(String.format( DS_FORMAT, domain.getFullyQualifiedDomainName(), - TTL_DS, + dnsDefaultDsTtl.getStandardSeconds(), dsData.getKeyTag(), dsData.getAlgorithm(), dsData.getDigestType(), @@ -304,7 +313,7 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA * ns.foo.tld 3600 IN AAAA 0:0:0:0:0:0:0:1 * } */ - private static String hostStanza(HostResource host) { + private static String hostStanza(HostResource host, Duration dnsDefaultATtl) { StringBuilder result = new StringBuilder(); for (InetAddress addr : host.getInetAddresses()) { // must be either IPv4 or IPv6 @@ -312,7 +321,7 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA result.append(String.format( A_FORMAT, host.getFullyQualifiedHostName(), - TTL_A, + dnsDefaultATtl.getStandardSeconds(), rrSetClass, addr.getHostAddress())); } diff --git a/javatests/google/registry/dns/writer/clouddns/CloudDnsWriterTest.java b/javatests/google/registry/dns/writer/clouddns/CloudDnsWriterTest.java index 710fba45b..ca7e9b5f6 100644 --- a/javatests/google/registry/dns/writer/clouddns/CloudDnsWriterTest.java +++ b/javatests/google/registry/dns/writer/clouddns/CloudDnsWriterTest.java @@ -76,7 +76,9 @@ public class CloudDnsWriterTest { private static final Inet6Address IPv6 = (Inet6Address) InetAddresses.forString("::1"); private static final DelegationSignerData DS_DATA = DelegationSignerData.create(12345, 3, 1, base16().decode("1234567890ABCDEF")); - private static final Duration DEFAULT_TTL = Duration.standardSeconds(180); + private static final Duration DEFAULT_A_TTL = Duration.standardSeconds(11); + private static final Duration DEFAULT_NS_TTL = Duration.standardSeconds(222); + private static final Duration DEFAULT_DS_TTL = Duration.standardSeconds(3333); @Mock private Dns dnsConnection; @Mock private Dns.ResourceRecordSets resourceRecordSets; @@ -101,7 +103,9 @@ public class CloudDnsWriterTest { dnsConnection, "projectId", "zoneName", - DEFAULT_TTL, + DEFAULT_A_TTL, + DEFAULT_NS_TTL, + DEFAULT_DS_TTL, RateLimiter.create(20), new SystemClock(), new Retrier(new SystemSleeper(), 5)); @@ -196,7 +200,7 @@ public class CloudDnsWriterTest { .setKind("dns#resourceRecordSet") .setType("NS") .setName(domainName + ".") - .setTtl((int) DEFAULT_TTL.getStandardSeconds()) + .setTtl((int) DEFAULT_NS_TTL.getStandardSeconds()) .setRrdatas(nameserverHostnames.build())); // Add glue for IPv4 in-bailiwick nameservers @@ -206,7 +210,7 @@ public class CloudDnsWriterTest { .setKind("dns#resourceRecordSet") .setType("A") .setName(i + ".ip4." + domainName + ".") - .setTtl((int) DEFAULT_TTL.getStandardSeconds()) + .setTtl((int) DEFAULT_A_TTL.getStandardSeconds()) .setRrdatas(ImmutableList.of(IPv4.toString()))); } } @@ -223,7 +227,7 @@ public class CloudDnsWriterTest { .setKind("dns#resourceRecordSet") .setType("NS") .setName(domainName + ".") - .setTtl((int) DEFAULT_TTL.getStandardSeconds()) + .setTtl((int) DEFAULT_NS_TTL.getStandardSeconds()) .setRrdatas(nameserverHostnames.build())); // Add glue for IPv6 in-bailiwick nameservers @@ -233,7 +237,7 @@ public class CloudDnsWriterTest { .setKind("dns#resourceRecordSet") .setType("AAAA") .setName(i + ".ip6." + domainName + ".") - .setTtl((int) DEFAULT_TTL.getStandardSeconds()) + .setTtl((int) DEFAULT_A_TTL.getStandardSeconds()) .setRrdatas(ImmutableList.of(IPv6.toString()))); } } @@ -250,7 +254,7 @@ public class CloudDnsWriterTest { .setKind("dns#resourceRecordSet") .setType("NS") .setName(domainName + ".") - .setTtl((int) DEFAULT_TTL.getStandardSeconds()) + .setTtl((int) DEFAULT_NS_TTL.getStandardSeconds()) .setRrdatas(nameserverHostnames.build())); } @@ -269,7 +273,7 @@ public class CloudDnsWriterTest { .setKind("dns#resourceRecordSet") .setType("DS") .setName(domainName + ".") - .setTtl((int) DEFAULT_TTL.getStandardSeconds()) + .setTtl((int) DEFAULT_DS_TTL.getStandardSeconds()) .setRrdatas(dsRecordData.build())); } diff --git a/javatests/google/registry/dns/writer/dnsupdate/DnsUpdateWriterTest.java b/javatests/google/registry/dns/writer/dnsupdate/DnsUpdateWriterTest.java index 9e21a07ab..72ab2f981 100644 --- a/javatests/google/registry/dns/writer/dnsupdate/DnsUpdateWriterTest.java +++ b/javatests/google/registry/dns/writer/dnsupdate/DnsUpdateWriterTest.java @@ -97,7 +97,7 @@ public class DnsUpdateWriterTest { createTld("tld"); when(mockResolver.send(any(Update.class))).thenReturn(messageWithResponseCode(Rcode.NOERROR)); - writer = new DnsUpdateWriter(Duration.ZERO, mockResolver, clock); + writer = new DnsUpdateWriter(Duration.ZERO, Duration.ZERO, Duration.ZERO, mockResolver, clock); } @Test diff --git a/javatests/google/registry/tools/server/GenerateZoneFilesActionTest.java b/javatests/google/registry/tools/server/GenerateZoneFilesActionTest.java index 12d10eacf..f581826d0 100644 --- a/javatests/google/registry/tools/server/GenerateZoneFilesActionTest.java +++ b/javatests/google/registry/tools/server/GenerateZoneFilesActionTest.java @@ -45,6 +45,7 @@ import java.net.InetAddress; import java.util.Map; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; +import org.joda.time.Duration; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -112,6 +113,9 @@ public class GenerateZoneFilesActionTest extends MapreduceTestCase response = action.handleJsonRequest(ImmutableMap.of( diff --git a/javatests/google/registry/tools/server/testdata/tld.zone b/javatests/google/registry/tools/server/testdata/tld.zone index fe0ea3661..b9c95453c 100644 --- a/javatests/google/registry/tools/server/testdata/tld.zone +++ b/javatests/google/registry/tools/server/testdata/tld.zone @@ -1,14 +1,14 @@ $ORIGIN tld. -ns.bar.tld 3600 IN A 127.0.0.1 -ns.bar.tld 3600 IN AAAA 0:0:0:0:0:0:0:1 +ns.bar.tld 11 IN A 127.0.0.1 +ns.bar.tld 11 IN AAAA 0:0:0:0:0:0:0:1 -ns-only.tld 180 IN NS ns.foo.tld. -ns-only.tld 180 IN NS ns.bar.tld. +ns-only.tld 222 IN NS ns.foo.tld. +ns-only.tld 222 IN NS ns.bar.tld. -ns-and-ds.tld 180 IN NS ns.foo.tld. -ns-and-ds.tld 180 IN NS ns.bar.tld. -ns-and-ds.tld 86400 IN DS 1 2 3 000102 +ns-and-ds.tld 222 IN NS ns.foo.tld. +ns-and-ds.tld 222 IN NS ns.bar.tld. +ns-and-ds.tld 3333 IN DS 1 2 3 000102 -ns.foo.tld 3600 IN A 127.0.0.1 -ns.foo.tld 3600 IN AAAA 0:0:0:0:0:0:0:1 +ns.foo.tld 11 IN A 127.0.0.1 +ns.foo.tld 11 IN AAAA 0:0:0:0:0:0:0:1