mirror of
https://github.com/google/nomulus.git
synced 2025-05-21 19:59:34 +02:00
mv com/google/domain/registry google/registry
This change renames directories in preparation for the great package rename. The repository is now in a broken state because the code itself hasn't been updated. However this should ensure that git correctly preserves history for each file.
This commit is contained in:
parent
a41677aea1
commit
5012893c1d
2396 changed files with 0 additions and 0 deletions
215
java/google/registry/dns/writer/dnsupdate/DnsUpdateWriter.java
Normal file
215
java/google/registry/dns/writer/dnsupdate/DnsUpdateWriter.java
Normal file
|
@ -0,0 +1,215 @@
|
|||
// Copyright 2016 The Domain Registry Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.domain.registry.dns.writer.dnsupdate;
|
||||
|
||||
import static com.google.common.base.Verify.verify;
|
||||
import static com.google.domain.registry.model.EppResourceUtils.loadByUniqueId;
|
||||
|
||||
import com.google.common.net.InternetDomainName;
|
||||
import com.google.domain.registry.config.ConfigModule.Config;
|
||||
import com.google.domain.registry.dns.writer.api.DnsWriter;
|
||||
import com.google.domain.registry.model.domain.DomainResource;
|
||||
import com.google.domain.registry.model.domain.secdns.DelegationSignerData;
|
||||
import com.google.domain.registry.model.host.HostResource;
|
||||
import com.google.domain.registry.model.registry.Registries;
|
||||
import com.google.domain.registry.util.Clock;
|
||||
|
||||
import org.joda.time.Duration;
|
||||
import org.xbill.DNS.AAAARecord;
|
||||
import org.xbill.DNS.ARecord;
|
||||
import org.xbill.DNS.DClass;
|
||||
import org.xbill.DNS.DSRecord;
|
||||
import org.xbill.DNS.Message;
|
||||
import org.xbill.DNS.NSRecord;
|
||||
import org.xbill.DNS.Name;
|
||||
import org.xbill.DNS.RRset;
|
||||
import org.xbill.DNS.Rcode;
|
||||
import org.xbill.DNS.TextParseException;
|
||||
import org.xbill.DNS.Type;
|
||||
import org.xbill.DNS.Update;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* A DnsWriter that implements the DNS UPDATE protocol as specified in
|
||||
* <a href="https://tools.ietf.org/html/rfc2136">RFC 2136</a>. Publishes changes in the
|
||||
* domain-registry to a (capable) external DNS server, sometimes called a "hidden master". DNS
|
||||
* UPDATE messages are sent via a "resolver" class which implements the network transport. For each
|
||||
* publish call, a single UPDATE message is created containing the records required to "synchronize"
|
||||
* the DNS with the current (at the time of processing) state of the registry, for the supplied
|
||||
* domain/host.
|
||||
*
|
||||
* <p>The general strategy of the publish methods is to delete <em>all</em> resource records of any
|
||||
* <em>type</em> that match the exact domain/host name supplied. And then for create/update cases,
|
||||
* add any required records. Deleting all records of any type assumes that the registry is
|
||||
* authoritative for all records for names in the zone. This seems appropriate for a TLD DNS server,
|
||||
* which should only contain records required for proper DNS delegation.
|
||||
*
|
||||
* <p>Only NS, DS, A, and AAAA records are published, and in particular no DNSSEC signing is done
|
||||
* assuming that this will be done by a third party DNS provider.
|
||||
*
|
||||
* <p>Each publish call is treated as an atomic update to the DNS. If an update fails an exception is
|
||||
* thrown, expecting the caller to retry the update later. The SOA record serial number is
|
||||
* implicitly incremented by the server on each UPDATE message, as required by RFC 2136. Care must
|
||||
* be taken to make sure the SOA serial number does not go backwards if the entire TLD (zone) is
|
||||
* "reset" to empty and republished.
|
||||
*/
|
||||
public class DnsUpdateWriter implements DnsWriter {
|
||||
|
||||
private final Duration dnsTimeToLive;
|
||||
private final DnsMessageTransport resolver;
|
||||
private final Clock clock;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param dnsTimeToLive TTL used for any created resource records
|
||||
* @param resolver a resolver used to send/receive the UPDATE messages
|
||||
* @param clock a source of time
|
||||
*/
|
||||
@Inject
|
||||
public DnsUpdateWriter(
|
||||
@Config("dnsUpdateTimeToLive") Duration dnsTimeToLive,
|
||||
DnsMessageTransport resolver,
|
||||
Clock clock) {
|
||||
this.dnsTimeToLive = dnsTimeToLive;
|
||||
this.resolver = resolver;
|
||||
this.clock = clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishDomain(String domainName) {
|
||||
DomainResource domain = loadByUniqueId(DomainResource.class, domainName, clock.nowUtc());
|
||||
try {
|
||||
Update update = new Update(toAbsoluteName(findTldFromName(domainName)));
|
||||
update.delete(toAbsoluteName(domainName), Type.ANY);
|
||||
if (domain != null && domain.shouldPublishToDns()) {
|
||||
update.add(makeNameServerSet(domainName, domain.loadNameservers()));
|
||||
update.add(makeDelegationSignerSet(domainName, domain.getDsData()));
|
||||
}
|
||||
|
||||
Message response = resolver.send(update);
|
||||
verify(
|
||||
response.getRcode() == Rcode.NOERROR,
|
||||
"DNS server failed domain update for '%s' rcode: %s",
|
||||
domainName,
|
||||
Rcode.string(response.getRcode()));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("publishDomain failed: " + domainName, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishHost(String hostName) {
|
||||
HostResource host = loadByUniqueId(HostResource.class, hostName, clock.nowUtc());
|
||||
try {
|
||||
Update update = new Update(toAbsoluteName(findTldFromName(hostName)));
|
||||
update.delete(toAbsoluteName(hostName), Type.ANY);
|
||||
if (host != null) {
|
||||
update.add(makeAddressSet(hostName, host.getInetAddresses()));
|
||||
update.add(makeV6AddressSet(hostName, host.getInetAddresses()));
|
||||
}
|
||||
|
||||
Message response = resolver.send(update);
|
||||
verify(
|
||||
response.getRcode() == Rcode.NOERROR,
|
||||
"DNS server failed host update for '%s' rcode: %s",
|
||||
hostName,
|
||||
Rcode.string(response.getRcode()));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("publishHost failed: " + hostName, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does nothing. Publish calls are synchronous and atomic.
|
||||
*/
|
||||
@Override
|
||||
public void close() {}
|
||||
|
||||
private RRset makeDelegationSignerSet(String domainName, Iterable<DelegationSignerData> dsData)
|
||||
throws TextParseException {
|
||||
RRset signerSet = new RRset();
|
||||
for (DelegationSignerData signerData : dsData) {
|
||||
DSRecord dsRecord =
|
||||
new DSRecord(
|
||||
toAbsoluteName(domainName),
|
||||
DClass.IN,
|
||||
dnsTimeToLive.getStandardSeconds(),
|
||||
signerData.getKeyTag(),
|
||||
signerData.getAlgorithm(),
|
||||
signerData.getDigestType(),
|
||||
signerData.getDigest());
|
||||
signerSet.addRR(dsRecord);
|
||||
}
|
||||
return signerSet;
|
||||
}
|
||||
|
||||
private RRset makeNameServerSet(String domainName, Iterable<HostResource> nameservers)
|
||||
throws TextParseException {
|
||||
RRset nameServerSet = new RRset();
|
||||
for (HostResource host : nameservers) {
|
||||
NSRecord record =
|
||||
new NSRecord(
|
||||
toAbsoluteName(domainName),
|
||||
DClass.IN,
|
||||
dnsTimeToLive.getStandardSeconds(),
|
||||
toAbsoluteName(host.getFullyQualifiedHostName()));
|
||||
nameServerSet.addRR(record);
|
||||
}
|
||||
return nameServerSet;
|
||||
}
|
||||
|
||||
private RRset makeAddressSet(String hostName, Iterable<InetAddress> addresses)
|
||||
throws TextParseException {
|
||||
RRset addressSet = new RRset();
|
||||
for (InetAddress address : addresses) {
|
||||
if (address instanceof Inet4Address) {
|
||||
ARecord record =
|
||||
new ARecord(
|
||||
toAbsoluteName(hostName), DClass.IN, dnsTimeToLive.getStandardSeconds(), address);
|
||||
addressSet.addRR(record);
|
||||
}
|
||||
}
|
||||
return addressSet;
|
||||
}
|
||||
|
||||
private RRset makeV6AddressSet(String hostName, Iterable<InetAddress> addresses)
|
||||
throws TextParseException {
|
||||
RRset addressSet = new RRset();
|
||||
for (InetAddress address : addresses) {
|
||||
if (address instanceof Inet6Address) {
|
||||
AAAARecord record =
|
||||
new AAAARecord(
|
||||
toAbsoluteName(hostName), DClass.IN, dnsTimeToLive.getStandardSeconds(), address);
|
||||
addressSet.addRR(record);
|
||||
}
|
||||
}
|
||||
return addressSet;
|
||||
}
|
||||
|
||||
private String findTldFromName(String name) {
|
||||
return Registries.findTldForNameOrThrow(InternetDomainName.from(name)).toString();
|
||||
}
|
||||
|
||||
private Name toAbsoluteName(String name) throws TextParseException {
|
||||
return Name.fromString(name, Name.root);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue